1

I am trying to achieve the next:

Parent:

public class Animal {
    private List<Animal> relatives;

    public List<Animal> getRelatives() {
        return relatives;
    }

    public void setRelatives(List<Animal> relatives) {
        this.relatives = relatives;
    }
}

Child:

public class Dog extends Animal {
    private List<Dog> relatives;

    public List<Dog> getRelatives() {
        return relatives;
    }

    public void setRelatives(List<Dog> relatives) {
       this.relatives = relatives;
    }
}

But for some reason, I get errors that the methods are clashing. Is this even possible with inheritance, without using generic types?

Andrew Tobilko
  • 48,120
  • 14
  • 91
  • 142
dendimiiii
  • 1,659
  • 3
  • 15
  • 26
  • maybe that helps: https://stackoverflow.com/questions/5346847/java-generic-method-inheritance-and-override-rules – ItFreak Sep 05 '19 at 15:12
  • This design would violate Liskov substitution principle. `Animal.getRelatives()` should return a `List`, so by Liskov substitution principle, `dog.getRelatives().add(new Cat())` must be ok. – Johannes Kuhn Sep 05 '19 at 15:16

2 Answers2

7

You don't really need to override/duplicate anything in the child class.

class Animal<Relative extends Animal<?>> {
  private List<? extends Relative> relatives;

  public List<? extends Relative> getRelatives() {
    return relatives;
  }

  public void setRelatives(List<? extends Relative> relatives) {
    this.relatives = relatives;
  }
}

class Dog extends Animal<Dog> {}
Andrew Tobilko
  • 48,120
  • 14
  • 91
  • 142
2

You could use generic and hold relatives in parent class. Additionally, you should aware of holding of unexpected modification:

public class Animal<T extends Animal<?>> {

    private final List<T> relatives = new ArrayList<>();

    public final List<T> getRelatives() {
        return relatives.isEmpty() ? Collections.emptyList() : Collections.unmodifiableList(relatives);
    }

    public final void addRelative(T relative) {
        Objects.requireNonNull(relative);
        relatives.add(relative);
    }
}

public class Dog extends Animal<Dog> {

    // just for test
    public List<Dog> getRelativesDogs() {
        return super.getRelatives();
    }

    // just for test
    public void addRelativeDog(Dog dog) {
        super.addRelative(dog);
    }

}
Oleg Cherednik
  • 17,377
  • 4
  • 21
  • 35