mardi 20 octobre 2020

Java: class inheritance and generic types

I'm currently working on inheritance in Java. I would like to discuss the following case with you.

In my example, I have numerous animal and enclosure classes. All animals are derived from BaseAnimal. All enclosure are derived from BaseEnclosure. Both base classes provide various concrete methods - but also some abstract methods.

Now, when implementing a CatEnclosure, I want to specify that when CatEnclosure.resettleTo(Enclosure) is called, only one Cat Enclosure can be passed. In my current code, a cat could also be placed with a dog.

To my understanding, I would have to define the class of the future (derived) class when creating the abstract method resettleTo in the BaseEnclosure class.

My idea was to use a second generic. So BaseEnclosure becomes BaseEnclosure <E, A>. But now I would also have to specify that E must be derived from BaseEnclosure. In addition, of course, A should also be of the BaseAnimal type.

So I get: BaseEnclosure <E extends BaseEnclosure, A extends BaseAnimal>

My IDE now complains that BaseEnclosure and BaseAnimal are raw types. If I write BaseEnclosure <E extends BaseEnclosure , A extends BaseAnimal <?,? >>, it works. However, I don't know whether all of this makes sense in terms of design.

I look forward to your suggestions.

Enclosed you get the example code.

public abstract class BaseAnimal<E> {
        protected E enclosure;
       
        public void setEnclosure(E enclosure) {
                this.enclosure = enclosure;
        }
       
        public E getEnclosure() {
                return enclosure;
        }
       
        public abstract String getNoise();
}
public abstract class BaseEnclosure<A> {
        protected List<A> animals = new ArrayList<A>();
       
        // some methods...
       
        public List<A> getAnimals() {
                return animals;
        }
       
        public abstract void resettleTo(BaseEnclosure other);
}
public class Cat extends BaseAnimal<CatEnclosure> {
 
        @Override
        public String getNoise() {
                return "miiiaaauu";
        }
}
public class CatEnclosure extends BaseEnclosure<Cat>{
 
        @Override
        public void resettleTo(BaseEnclosure other) {
                // hm...
        }
}
public class Dog extends BaseAnimal<DogEnclosure> {
 
        @Override
        public String getNoise() {
                return "wuff";
        }
}
public class DogEnclosure extends BaseEnclosure<Dog>{
 
        // some methods...
       
        @Override
        public void resettleTo(BaseEnclosure other) {
                // hm...
        }
}
public class Main {
       
        public static void main(String[] args) {
                DogEnclosure doghouse = new DogEnclosure();
                Dog dog = new Dog();
                // later: JPA
                doghouse.getAnimals().add(dog);
                dog.setEnclosure(doghouse);
               
                CatEnclosure catbox = new CatEnclosure();
                Cat cat = new Cat();
                // later: JPA
                catbox.getAnimals().add(cat);
                cat.setEnclosure(catbox);
               
                // OHOHOH!!!
                doghouse.resettleTo(catbox);
        }
}

Aucun commentaire:

Enregistrer un commentaire