Inheritance vs Composition
Combination is better than inheritance, use more combination less inheritance.
The disadvantage of inheritance is when the tree of inheritance is too deep or too wide, it's hard to maintain and shared the codes among the classes.
For exemple, we want to create a class Ostrich
. It can fly and lay eggs. If we use inheritance, we need to create 6 parents classes!
Bird - | - FlyBird - | - FlyAndLayeggBird
| _ _ | - FlyNotLayeggBird
| - LayeggBrid - | - LayeggNotFlyBrid
If we use combination.
public interface Flyable {
void fly();
}
public class FlyAbility implements Flyable {
@Override
public void fly() { //... }
}
//省略Tweetable/TweetAbility/EggLayable/EggLayAbility
public class Ostrich implements Tweetable, EggLayable { //鸵鸟
private TweetAbility tweetAbility = new TweetAbility(); // combination
private EggLayAbility eggLayAbility = new EggLayAbility(); // combination
//... 省略其他属性和方法...
@Override
public void tweet() {
tweetAbility.tweet(); // delegation
}
@Override
public void layEgg() {
eggLayAbility.layEgg(); // delegation
}
}
To sum up:
-
If the there are ONLY two layer in inheritance tree, the relation between the classes is simple. We can use inheritance.
-
If the relation between the classes is complicate, we use combination.
4 relationships between the classes
-
Generalization
It's inheritance.
public class A { ... } public class B extends A { ... }
-
Realization
It's implementation of the interface.
public interface A {...} public class B implements A { ... }
-
Aggregation
It's like Dependency Injection.
If the instance of class A is destroyed, that of the class B still exists. (Teacher and Student)
public class A { private B b; public A(B b) { this.b = b; } }
-
Composition
If the instance of class A is destroyed, that of the class B is destroyed, too. (Car and Wheel)
public class A { private B b; public A() { this.b = new B(); } }