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?

ggrr
  • 5,725
  • 11
  • 35
  • 37
  • 1
    Possible duplicate of [Why is Clean Code suggesting avoiding protected variables?](http://programmers.stackexchange.com/questions/162643/why-is-clean-code-suggesting-avoiding-protected-variables) – gnat Jun 22 '16 at 08: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 '16 at 08: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 '16 at 10:47

1 Answers1

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.

JacquesB
  • 57,310
  • 21
  • 127
  • 176
  • 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 '16 at 10:44
  • 4
    @DavidArno: There is something wrong with inheritance used inappropriately. But this is the same with any feature. – JacquesB Jun 22 '16 at 10:58
  • 1
    even when used "appropriately", inheritance causes all sorts of problems around creating coupling, including the dreaded ["fragile base class problem](https://en.wikipedia.org/wiki/Fragile_base_class), weakening encapsulation and making testing harder. Have a read of "[Inheritance: just stop using it already](http://www.davidarno.org/2016/02/04/inheritance-just-stop-using-it-already/)" – David Arno Jun 22 '16 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 '16 at 08:33
  • @arno Something very wrong with comments that don't take common sense into consideration. – gnasher729 Jun 01 '17 at 08:34
  • 1
    @arno so you are telling me I cannot inherit from UIView? Dogma hurts. Don't advocate blind obedience to dogma. – gnasher729 Jun 01 '17 at 08:36
  • @gnasher729 Cargo-cult programming or silver bullet. – Walfrat Jun 01 '17 at 12:03
  • Fine, there are some cases where inheritance is fine, but this is sure not one of them! What happens when you need a Bird class? Are you going to add a fly method to animal? "Of course not" you reply. But then what happens when you need to add a bat? Just say no to inheritance, it is not worth it. It is too hard for 99% of people to discern when or when not it is appropriate. – TheCatWhisperer May 02 '18 at 16:50
  • @TheCatWhisperer: So you argue against using inheritance in one case because it would be inappropriate in another different case? There is no golden hammer which is the correct tool for everything. I'm sure you can also find people misusing composition. – JacquesB May 02 '18 at 17:08
  • @JacquesB Some people survive jumping off a cliff, but jumping off a cliff is still a bad idea. I've not seen examples of compositional typing causing coupling problems – TheCatWhisperer May 02 '18 at 18:19