我有一个类层次结构,像这个饮料 – >咖啡 – >拿铁.
当饮料是由咖啡延伸的抽象超类.咖啡类然后添加一些行为,但也是抽象的.拿铁延伸咖啡班,是一个具体的班级.我使用继承来添加行为.而继承确实有超类方法的可见性的缺点,使代码变得脆弱,代码紧密耦合.因此,编程原理规定组合应优于继承.但在这种情况下,继承感觉如此自然,因为Latte是一种咖啡和咖啡是一种使用组合添加行为的饮料,尽管有其好处.所以这里的问题是
应该直觉超越设计原则?
当饮料是由咖啡延伸的抽象超类.咖啡类然后添加一些行为,但也是抽象的.拿铁延伸咖啡班,是一个具体的班级.我使用继承来添加行为.而继承确实有超类方法的可见性的缺点,使代码变得脆弱,代码紧密耦合.因此,编程原理规定组合应优于继承.但在这种情况下,继承感觉如此自然,因为Latte是一种咖啡和咖啡是一种使用组合添加行为的饮料,尽管有其好处.所以这里的问题是
应该直觉超越设计原则?
饮料:
public abstract class Beverage {
private final String name;
private final double price;
Beverage(String name,double price){
this.name = name;
this.price = price;
}
public String getName() {
return name;
}
public double getPrice() {
return price;
}
public abstract void make();
}
咖啡:
public abstract class Coffee extends Beverage {
public Coffee(String name,double price) {
super(name,price);
}
public final void make(){
grindBeans();
takeShot();
frothMilk();
addCondiments();
}
public void grindBeans(){
System.out.println("Grinding Beans...");
}
public void takeShot(){
System.out.println("Taking Shot....");
}
public abstract void frothMilk();
public abstract void addCondiments();
}
拿铁:
public class Latte extends Coffee {
public Latte() {
super("Latte",4.0);
}
@Override
public void frothMilk() {
System.out.println("Frothing milk to create micro foam");
}
@Override
public void addCondiments() {
// Todo Auto-generated method stub
}
}
编辑:向现有结构添加糖.只显示新的代码.
public abstract class Beverage {
private Sugar sugar;
public Sugar getSugar() {
return sugar;
}
public void setSugar(Sugar sugar) {
this.sugar = sugar;
}
}
咖啡:
public abstract class Coffee extends Beverage {
public final void make(){
grindBeans();
takeShot();
frothMilk();
addSugar();
addCondiments();
}
public void addSugar(){
Sugar sugar = super.getSugar();
if(!(sugar instanceof NoSugar)){
System.out.println("adding " + sugar.getTeaspoon() + " teaspoon sugar");
}
}
解决方法
虽然组合与遗产有很多好处,但使用继承感觉是自然的(即在真正的关系中)没有任何问题.如果它是自然的,请继续使用它.