0

As I know, according to "composition over inheritance" rule, we should avoid reusing a method by inheritance, but how about class members? Suppose I have parent and child classes like the following:

public class Animal{
    protected String name;
    protected int _id;
    public String getName(){
        return name;
    }
    public int getId(){
        return _id;
    }
}

public class Cat extends Animal{
}

public class Dog extends Animal{
}

and I found I am reusing "name" and "_id" field by inheritance. Should I put all attributes into a separate class and let a child class uses it by composition like this:

public class AnimalData{
    public String name;
    public int _id;
}

public interface Animal{
    public AnimalData getAnimalData();
}

public class Cat implements Animal{
    public AnimalData animalData;
    public AnimalData getAnimalData(){
        return animalData;
    }
} 

public class Dog implements Animal{
    public AnimalData animalData;
    public AnimalData getAnimalData(){
        return animalData;
    }
} 

in order to obey "composition over inheritance" rule?

3
  • 1
    Possible duplicate of Why is Clean Code suggesting avoiding protected variables?
    – gnat
    Jun 22, 2016 at 8:06
  • If your interface method is always implemented the same way inside your child classes doesn't it makes more sense to turn the interface into a(n) (abstract) class ? I feel like your example is too simple to show problems you face extending functionality and structuring your program
    – Diane M
    Jun 22, 2016 at 8:46
  • It's difficult to tell from your example code what you are doing in reality. As it stands, there is no reason to have the separate Cat and Dog classes. Could you improve your example to better explain why you need extra classes?
    – David Arno
    Jun 22, 2016 at 10:47

1 Answer 1

5

There is nothing wrong with inheritance, and in in your case it is clearly the simplest solution. The second solution introduces complexity for no benefit. "Composition over inheritance" is just a rule-of-thumb to avoid over-reliance in inheritance - it does not say you shouldn't use inheritance when it is appropriate.

Furthermore, you are not even reducing the amount of inheritance in the second example. The question is if you need the subclasses "Cat" and "Dog" at all. It is easier to see if you use a more real world example. Say you have a Button. You realize than some instances of Button will have a popup-help, and some will not. Should you create a subclass ButtonWithPopupHelp which adds the popup-related functionality, or should you rather create a separate class PopupHelp, which contains the popup-specific functionality, and which can be attached to the button and perhaps other controls? If possible, the second options is preferable.

10
  • 1
    "There is nothing wrong with inheritance" -1 for that.This is an untrue statement, as there is LOTS wrong with inheritance.
    – David Arno
    Jun 22, 2016 at 10:44
  • 4
    @DavidArno: There is something wrong with inheritance used inappropriately. But this is the same with any feature.
    – JacquesB
    Jun 22, 2016 at 10:58
  • 1
    even when used "appropriately", inheritance causes all sorts of problems around creating coupling, including the dreaded "fragile base class problem, weakening encapsulation and making testing harder. Have a read of "Inheritance: just stop using it already"
    – David Arno
    Jun 22, 2016 at 11:14
  • @DavidArno: The phase "Favor composition over inheritance" is from the GoF design patterns book, I believe. They certainly does not say you should never use inheritance.
    – JacquesB
    Jun 23, 2016 at 8:33
  • 1
    @arno so you are telling me I cannot inherit from UIView? Dogma hurts. Don't advocate blind obedience to dogma.
    – gnasher729
    Jun 1, 2017 at 8:36

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.