关于“优先考虑组成而不是继承”这一主题,我的老师说:
我对这三个概念不太了解,因此我尝试写下一些代码:
//Composition is this
Class A{
public void doSomething(){
//do some code
}
}
Class B{
A a = new A();
public void doOther(){
a.doSomething(); //this is forwarding
}
}
那么包装是什么呢?
最佳答案
您的第一个例子不是合成。
Composition是2个对象之间的“has-a”关系,其中一个对象(组成的对象)是另一个对象(所有者)的字段成员。
组成为:
class DemoA {
DemoB b; //composition
}
我们会说“DemoA由DemoB组成”。
如果当
DemoB
变得不可访问时DemoA
对象仍然可用,我们认为DemoB
为aggregated。例如,尽管密钥环可能已损坏,但仍可以使用密钥。密钥环将由密钥组成,但不拥有密钥,这表示聚合。您的转发示例看起来不错,尽管要求确实说“返回结果”,这可能表明方法不应无效:
class DemoA {
private DemoB b;
public int doSomething() {
return b.doSomething(); //forwarding/delegating
}
}
至于包装器,它们封装了对象的行为,从而暴露了新的(通常是更复杂的)行为。一个示例就是
DataInputStream
,当InputStream
仅能处理原始数据时,它包装String
以允许您阅读InputStream
对象及更多对象。class DemoB {
public int read() {
//...Read one int of data
}
}
class DemoA {
private DemoB b;
public DemoA(DemoB b) {
this.b = b;
}
public List<Integer> readUntil(List<Integer> dataList, Supplier<Boolean> condition) {
while(condition.get())
dataList.add(b.read());
return dataList;
}
}
在此示例中,
DemoA
包装了DemoB
以暴露readUntil
行为,但DemoB
无法做到这一点。这是一个愚蠢的示例,但希望表达这一点:我们的
DemoB
对象无法执行所需的行为(readUntil),因此我们将其包装为可为我们处理该行为的类型,因此我们不会不断重写此类行为。