我有一个类层次结构,像这个饮料 – >咖啡 – >拿铁.
当饮料是由咖啡延伸的抽象超类.咖啡类然后添加一些行为,但也是抽象的.拿铁延伸咖啡班,是一个具体的班级.我使用继承来添加行为.而继承确实有超类方法的可见性的缺点,使代码变得脆弱,代码紧密耦合.因此,编程原理规定组合应优于继承.但在这种情况下,继承感觉如此自然,因为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"); } }
解决方法
虽然组合与遗产有很多好处,但使用继承感觉是自然的(即在真正的关系中)没有任何问题.如果它是自然的,请继续使用它.