一个月前我问了类似的问题:Inheritance though composition?
我从这篇文章中提取了示例:http://www.javaworld.com/javaworld/jw-11-1998/jw-11-techniques.html?page=1 但是,这次是另一个问题。很抱歉发布了很多代码,但它只是很长,读起来并不难。
class Fruit {
public int peel() {
System.out.println("Peeling is appealing.");
return 1;
}
}
class Apple extends Fruit {
}
class Example1 {
public static void main(String[] args) {
Apple apple = new Apple();
int pieces = apple.peel();
}
}
修改后,它不再适用:
class Peel {
private int peelCount;
public Peel(int peelCount) {
this.peelCount = peelCount;
}
public int getPeelCount() {
return peelCount;
}
}
类Fruit的修改导致编译错误代码。
class Peel {
private int peelCount;
public Peel(int peelCount) {
this.peelCount = peelCount;
}
public int getPeelCount() {
return peelCount;
}
}
class Fruit {
// Return a Peel object that
// results from the peeling activity.
public Peel peel() {
System.out.println("Peeling is appealing.");
return new Peel(1);
}
}
旧的实施已经破裂。这个问题可以通过组合来解决:
class Peel {
private int peelCount;
public Peel(int peelCount) {
this.peelCount = peelCount;
}
public int getPeelCount() {
return peelCount;
}
}
class Fruit {
// Return int number of pieces of peel that
// resulted from the peeling activity.
public Peel peel() {
System.out.println("Peeling is appealing.");
return new Peel(1);
}
}
// Apple must be changed to accomodate
// the change to Fruit
class Apple {
private Fruit fruit = new Fruit();
public int peel() {
Peel peel = fruit.peel();
return peel.getPeelCount();
}
}
// This old implementation of Example2
// still works fine.
class Example1 {
public static void main(String[] args) {
Apple apple = new Apple();
int pieces = apple.peel();
}
}
凭借构图风格,苹果不再是与水果的关系。它变成了一个。来自Fruit的方法被委托给Apple作为继承。我的问题出现了:
使用包装方法从Fruit委托方法,是不是促进了复制和粘贴,这是一种不好的做法?如果我们在Fruit中有大约10-50个方法的图像。如果有大约50个子类要继承,怎么能通过组合继承?
关于第一个例子,通过使用扩展继承,作者建议超类中的一个更改将破坏使用它的实现。但是,我想知道,为什么需要改变?是否OO原则之一“关闭修改,开放延伸”?在作者声明的情况下,我仍然可以保留旧的超类实现,并仍然使其适应新的更改。像这样:
类水果{
// Return a Peel object that
// results from the peeling activity.
private Peel getPeel() {
System.out.println("Peeling is appealing.");
return new Peel(1);
}
public int peel(){
Peel peel = getPeel();
return peel.getPeelCount();
}
}
向超类添加新方法以适应而不是更改或替换旧方法是否有问题,这会破坏程序结构?据我所知,通过这样做,我仍然可以实现与组合示例相同的事情,并且我不必为很多子包的方法来为每个子类委托超类的方法。
界面谈话{
public void talk();
}
Animal class family可以实现Talkative接口以及Person类系列。您如何看待我的结论?
答案 0 :(得分:3)
基本上,您似乎试图通过创建包装类来避免更改依赖于旧API的客户端。
不幸的是,这种方法效果不佳。它导致包装类的增加,以及其他的创建包装类的实例。如果你做了很多这样的事情,你的代码库/应用程序会变得臃肿,性能会受到影响,而且你的代码越来越难以理解。
更好的方法是:
@Deprecated标签允许您向人们发送API,警告不再使用某个方法,同时为他们提供一个窗口,用于修复其代码以使用替换方法/替代方法。