return 1;
}
//需求改变后,将上面方法修改后的新接口
public Peel peel() {
return new Peel(1); //另外一个类
}
}
class Apple {
private Fruit fruit = new Fruit();
public int peel() {
return fruit.peel();
//使用Fruit的新接口,用于取代上面一行代码
Peel peel = fruit.peel();
return peel.getPeelCount();
}
}
class Example2 {
public static void main(String[] args) {
Apple apple = new Apple();
int pieces = apple.peel(); //这里不会有任何影响
}
}
在合成实现方式中,subclass变为front-end class,superclass变为back-end class。使用继承,subclass自动继承了superclass的non-private方法;使用合成,front-end class必须在自身的实现中明确的调用back-end class中的相应的方法。这种直接调用有时被称为“推进(forwarding)”或“委派(delegating)”这个方法的调用到back-end对象。
合成比继承提供了更强壮的在代码重用方面的封装,因为back-end class的修改不会波及任何依赖front-end class的代码。例如我们要将Fruit的peel方法返回值修改为Peel(上面红色部分),同时你会看到Apple的peel方法有相应的改变,这时对Fruit接口的修改将不会影响到Example2的代码,
比较合成与继承
几点对比:
back-end class(合成)比superclass(继承)更容易修改接口。就像前面举例说明的那样,back-end class接口的改变必将导致front-end class实现的改变,但不会影响到front-end class的接口,所以依赖front-end class的代码将正常工作。作为对比,superclass接口的修改不仅波及subclass层,也会影响到所有直接使用superclass接口以及使用subclass接口的地方
front-end class(合成)比subclass(继承)更容易修改接口。正像superclass是脆弱(fragile)的,而subclass是坚硬(rigid)的。你不能只改变subclass的接口而不去确认新接口是否和父类型(supertypes)兼容。例如,你不能在subclass中添加一个与superclass方法同样特征但返回值类型不同的新方法。合成则允许你修改front-end class的接口,而不用关心back-class。
合成允许你延迟back-end objects的创建,直到他们被需要的时候才创建,在front-end object的生命期内可以动态的改变back-end objects。对于继承来说,一旦subclass被创建了,你就可以通过subclass object来获取superclass的某些资源了,在subclass生命期内一直保持着superclass的对象,也就是说,subclass object一旦被创建,superclass就已知且不可改变了。
添加subclasses(继承)比添加front-end class(合成)更容易。因为继承伴随多态。如果你的一些代码仅依赖superclass,那么不用任何修改,你就能够使用一个新的subclass。对于合成来说就不可以,除非你使用带有接口的合成(composition with interfaces)。合成和接口的共同使用将提供一个非常强大的设计工具。
同使用subclass中从继承superclass来的方法实现相比,合成中的直接的方法调用委派经常(often)有性能损耗。Often的意思是说,因为性能依赖众多因素,比如JVM优化并执行程序的能力。
对于合成和继承来说,修改任何class的实现都是简单的。实现改变引起的连锁反映被保留在同一个class
在合成和继承中作出选择
怎么作出选择呢?这里有一个指导方针来让我们趋向合成与继承中的其中一个
继承是is-a的关系
主要是说,继承应该只被用在“subclass is-a superclass”的时候。在上面例子中,Apple is-a Fruit,所以我们倾向使用继承。
当你认为已经有一个is-a关系的时候,你需要问自己 一个非常重要的问题,那就是这个“is-a 关系”是否在应用程序或代码生命周期中保持不变的(constant)。举例:当Employee在某个时间段扮演的角色是Person的时候,你可能认为 Employee is
}
//需求改变后,将上面方法修改后的新接口
public Peel peel() {
return new Peel(1); //另外一个类
}
}
class Apple {
private Fruit fruit = new Fruit();
public int peel() {
return fruit.peel();
//使用Fruit的新接口,用于取代上面一行代码
Peel peel = fruit.peel();
return peel.getPeelCount();
}
}
class Example2 {
public static void main(String[] args) {
Apple apple = new Apple();
int pieces = apple.peel(); //这里不会有任何影响
}
}
在合成实现方式中,subclass变为front-end class,superclass变为back-end class。使用继承,subclass自动继承了superclass的non-private方法;使用合成,front-end class必须在自身的实现中明确的调用back-end class中的相应的方法。这种直接调用有时被称为“推进(forwarding)”或“委派(delegating)”这个方法的调用到back-end对象。
合成比继承提供了更强壮的在代码重用方面的封装,因为back-end class的修改不会波及任何依赖front-end class的代码。例如我们要将Fruit的peel方法返回值修改为Peel(上面红色部分),同时你会看到Apple的peel方法有相应的改变,这时对Fruit接口的修改将不会影响到Example2的代码,
比较合成与继承
几点对比:
back-end class(合成)比superclass(继承)更容易修改接口。就像前面举例说明的那样,back-end class接口的改变必将导致front-end class实现的改变,但不会影响到front-end class的接口,所以依赖front-end class的代码将正常工作。作为对比,superclass接口的修改不仅波及subclass层,也会影响到所有直接使用superclass接口以及使用subclass接口的地方
front-end class(合成)比subclass(继承)更容易修改接口。正像superclass是脆弱(fragile)的,而subclass是坚硬(rigid)的。你不能只改变subclass的接口而不去确认新接口是否和父类型(supertypes)兼容。例如,你不能在subclass中添加一个与superclass方法同样特征但返回值类型不同的新方法。合成则允许你修改front-end class的接口,而不用关心back-class。
合成允许你延迟back-end objects的创建,直到他们被需要的时候才创建,在front-end object的生命期内可以动态的改变back-end objects。对于继承来说,一旦subclass被创建了,你就可以通过subclass object来获取superclass的某些资源了,在subclass生命期内一直保持着superclass的对象,也就是说,subclass object一旦被创建,superclass就已知且不可改变了。
添加subclasses(继承)比添加front-end class(合成)更容易。因为继承伴随多态。如果你的一些代码仅依赖superclass,那么不用任何修改,你就能够使用一个新的subclass。对于合成来说就不可以,除非你使用带有接口的合成(composition with interfaces)。合成和接口的共同使用将提供一个非常强大的设计工具。
同使用subclass中从继承superclass来的方法实现相比,合成中的直接的方法调用委派经常(often)有性能损耗。Often的意思是说,因为性能依赖众多因素,比如JVM优化并执行程序的能力。
对于合成和继承来说,修改任何class的实现都是简单的。实现改变引起的连锁反映被保留在同一个class
在合成和继承中作出选择
怎么作出选择呢?这里有一个指导方针来让我们趋向合成与继承中的其中一个
继承是is-a的关系
主要是说,继承应该只被用在“subclass is-a superclass”的时候。在上面例子中,Apple is-a Fruit,所以我们倾向使用继承。
当你认为已经有一个is-a关系的时候,你需要问自己 一个非常重要的问题,那就是这个“is-a 关系”是否在应用程序或代码生命周期中保持不变的(constant)。举例:当Employee在某个时间段扮演的角色是Person的时候,你可能认为 Employee is
| 对此文章发表了评论 |
