0

I am facing a downcast issue in my company software and I can't manage to find a workaround. (It's something put in place and I cannot change the whole conception)

I will try to give you the whole context with an example: Basically, we have 2 software components, let's say BrickHigh, BrickLow. BrickLow can use everything from BrickHigh but BrickHigh can't see Bricklow.

In BrickHigh there is an Animal class (dozens of attributes) with its DAO :

public class Animal .. {
 //attributes...
}

In BrickLow I have created a Cat class (dozens of unmapped attributes aswell) which extends Animal.

public class Cat extends Animal {
//attributes
}

What was intended to do is to have a super class(Animal) with every mapped attribute. But I cannot use my animal class in my application because it would be too many changes since the whole app uses Cat.

But obviously, I cannot cast my Animal to Cat after getting it from the DAO since Java doesn't allow it, and I need every information from Animal.

Since my BrickHigh doesn't see my BrickLow, there are no such things as Animal animal = new Cat(); possible.

My first idea was to create a constructor in Cat that would take an Animal as parameter

public Cat(Animal a) {
 super(a);
}

But what my constructor must be in my Animal class? It doesn't seem to work.

rilent
  • 659
  • 1
  • 6
  • 22
  • 2
    Without a concrete example that *clearly* illustrates the problem, this is all just mumbo-jumbo that doesn't really make much sense. I understand that you're trying to avoid posting NDA'd code but what you currently have here is a mere theoretical problem that is hard to explain, with delicate details lost in the translation. – Shark Jul 06 '17 at 12:23
  • 2
    its really hard to understand when you start using own custom terminology like "mother class" (it is super class, right?) – Sharon Ben Asher Jul 06 '17 at 12:23
  • It's also hard to resolve "In BrickLow I have created a Cat class" with "it would be too many changes since the whole app uses Cat". I agree we need a better explanation of what you're trying to do *overall*, and certainly using standard Java terms would help. When you say "In BrickLow I have created a Cat class", do you mean it's internal? – arcy Jul 06 '17 at 12:31
  • 1
    You can access Cat class and its instance variables (or getter/setter methods) in BrickHigh via reflection. This is me guessing .... – Sharon Ben Asher Jul 06 '17 at 12:31
  • Thank you for your inputs, I have tried to edit it, but I have maybe made it worse. – rilent Jul 06 '17 at 12:45

2 Answers2

2

But what my constructor must be in my Animal class? It doesn't seem to work.

Something like this:

   public Animal(Animal other) {
      this.field1 = other.field1;
      this.field2 = other.field2;
      // etc
   }

However, I think may be better off using the Object Factory pattern; i.e. have your DAO class take a parameter which is a factory object that can create Animal instances. When you use the DAO (from BrickHigh) in code that uses the BrickLow APIs, you instantiate if with a factory that produces Cat instances rather than Animal instances.

Stephen C
  • 698,415
  • 94
  • 811
  • 1,216
1

I'm not sure I understand fully your question, but if you want to create an instance of some animal class from within the code of BrickHigh, but without having any knowledge of BrickLow, you could either use a factory, or a Class object that would be identified by one or more attributes of the DAO.

For instance:

public interface AnimalFactory {
    boolean canInstanciate(AnimalDAO dao);
    Animal instanciate(AnimalDAO dao);
}

Your BrickHigh would then have a set of factories, and would supply a mechanism to register new factories.

For instance:

public enum AnimalFactories implements AnimalFactory {
    INSTANCE;

    private List<AnimalFactory> factories = new ArrayList<>();


    public void registerFactory(AnimalFactory factory) {
        factories.add(factory);
    }

    @Override
    public boolean canInstanciate(AnimalDAO dao) {
        for (AnimalFactory fac: factories) {
            if (fac.canInstanciate(dao)) {
                return true;
            }
        }
        return false;
    }

    @Override
    public Animal instanciate(AnimalDAO dao) {
        for (AnimalFactory fac: factories) {
            if (fac.canInstanciate(dao)) {
                return fac.instanciate(dao);
            }
        }
        throw new InstanciationException("No factory for that animal");
    }
}
Maurice Perry
  • 9,261
  • 2
  • 12
  • 24