- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
你能帮我理解下面写的内容吗?这是来自 Thinking in Java 一书。
Because you are composing a new class from existing classes, this concept is called composition(if the composition happens dynamically, it's usually called aggregation).
Composition is often referred to as a "has-a" relationship, as in "A car has an engine."
Composition comes with a great deal of flexibility. The member objects of your new class are typically private, making them inaccessible to the client programmers who are using the class. This allows you to change those members without disturbing existing client code. You can also change the member objects at runtime, to dynamically change the behavior of your program. Inheritance, which is described next, does not have this flexibility since the compiler must place compile-time restrictions on classes created with inheritance.
Because inheritance is so important in object-oriented programming, it is often highly emphasized, and the new programmer can get the idea that inheritance should be used everywhere. This can result in awkward and overly complicated designs. Instead, you should first look to composition when creating new classes, since it is simpler and more flexible.
没有例子我就无法捕获这个果冻。您能给我提供以下示例吗:
聚合,即动态发生的组合。
继承面临编译时限制。
我的意思是,我正在寻找揭示组合相对于继承的优势的示例。
稍后添加:我需要代码示例(而不是描述)。
最佳答案
I mean that I'm looking for examples revealing advantages of composition over inheritance.
假设您有一个顶级抽象AbstractCar
。如果你要创建一个强大的继承关系,你会有类似的东西
abstract class AbstractCar {
protected abstract void startEngine();
}
class FastCar extends AbstractCar {
@Override
public void startEngine() {
System.out.println("turn key... vroom");
}
}
就功能而言,这看起来很符合要求,因为汽车应该具有启动发动机的功能。但是,如果您想关闭发动机或为发动机安装插入启动功能,该怎么办?您必须更改实现。
更好的方法是将引擎功能提取到 Engine
类中,并将其封装到 AbstractCar
中。 Engine
将是一个顶级抽象,其实现可以更改,并且您可以使用 Engine
作为类型,同时允许引擎实现更改。例如
interface Engine {
void startEngine();
}
class PushStartEngine implements Engine {
@Override
public void startEngine() {
System.out.println("push button.. vrooom");
}
}
abstract class AbstractCar {
protected Engine engine;
protected void setEngine(Engine engine) {
this.engine = engine;
}
protected void getEngine() {
return engine;
}
}
class FastCar extends AbstractCar {
public FastCar() {
setEngine(new KeyStartEngine());
}
}
这可能不是最好的示例(因为它仍然强加了紧密的类型耦合 - 还有其他设计模式可以解决这个问题),但它应该为您提供组合相对于继承的优势的示例。提取变化的基本前提是,在本例中是引擎。在字符串继承关系中,您可能会在顶级抽象中定义更多功能,但是当您喜欢组合继承时,您可以将该功能封装到其他对象中。这允许更轻松的扩展和更改。
因此,通过上面的示例,您现在可以轻松切换引擎,这在继承的情况下是不可能的
public static void main(String[] args) {
// let's say you have another OlderCar implmentation
// that has a KeyStartEngine
OlderCar car = new OlderCar();
car.getEngine().startEngine();
// I just hit the lotto, lets upgrade!
PushStartEngine engine = store.buyPushStartEngine();
car.setEngine(engine);
car.getEngine().startEngine();
}
关于java - 组合与继承(如何理解 Java 中的 Thinking),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24464947/
我使用的是 PHP 5.3 稳定版,有时会遇到非常不一致的行为。据我所知,在继承中,父类(super class)中的所有属性和方法(私有(private)、公共(public)和 protected
所以我一直在努力寻找正确的方法来让应该非常简单的继承发挥作用(以我想要的方式 ;)),但我失败得很惨。考虑一下: class Parent { public String name = "Pare
给定这些类: class Father { public Father getMe() { return this; } } class Child extends Father {
为什么最后打印“I'm a Child Class”。 ? public class Parent { String parentString; public Parent()
我知道有很多类似的问题对此有很多很好的答案。我试着看看经典的继承方法,或者那些闭包方法等。不知何故,我认为它们对我来说或多或少是“hack”方法,因为它并不是 javascript 设计的真正目的。
我已经使用表单继承有一段时间了,但没有对以下方法进行太多研究。只需创建一个新类而不是表单并从现有表单继承并根据需要将所需控件转换为 protected 。 Visual Studio 2010 设计器
我原以为下面的代码片段会产生编译错误,因为派生类不会有我试图在 pub_fun() 中访问的 priv_var。但是它编译了,我得到了下面提到的输出。有人可以解释这背后的理论吗? class base
继承的替代方案有哪些? 最佳答案 Effective Java:优先考虑组合而不是继承。 (这实际上也来自《四人帮》)。 他提出的情况是,如果扩展类没有明确设计为继承,继承可能会导致许多不恰当的副作用
我有2个类别:动物( parent )和狗(动物的“ child ”),当我创建一个 Animal 对象并尝试提醒该动物的名称时,我得到了 undefined ,而不是她的真名。为什么?(抱歉重复发帖
我试图做继承,但没想到this.array会像静态成员一样。我怎样才能让它成为“ protected /公开的”: function A() { this.array = []; } func
在创建在父类中使用的 lambda 时,我试图访问子类方法和字段。代码更容易解释: class Parent { List> processors; private void do
如果我有一个对象,我想从“ super 对象”“继承”方法以确保一致性。它们将是混合变量。 修订 ParentObj = function() { var self = this; t
class Base { int x=1; void show() { System.out.println(x); } } class Chi
目前我正在尝试几种不同的 Javascript 继承方法。我有以下代码: (“借用”自 http://www.kevlindev.com/tutorials/javascript/inheritanc
我在 .popin-foto 元素中打开一个 popin。当我尝试在同一元素中打开子类 popin 时,它不起作用。 代码 这是 parent function Popin(container, ti
我有以下两个类: class MyClass { friend ostream& operatorvalue +=1; return *this; } 现在
有没有办法完全忽略导入到 html 文件中的 header 中的 CSS 文件? 我希望一个页面拥有自己独立的 CSS,而不是从任何其他 CSS 源继承。 最佳答案 您可以在本地样式表中使用 !imp
Douglas Crockford似乎喜欢下面的继承方式: if (typeof Object.create !== 'function') { Object.create = functio
假设我有以下代码: interface ISomeInterface { void DoSomething(); void A(); void B(); } public
class LinkedList{ public: int data; LinkedList *next; }; class NewLinkedList: public Lin
我是一名优秀的程序员,十分优秀!