The two most common techniques for reusing functionality in object-oriented systems are class inheritance
and object composition. As we've explained, class inheritance lets you define the implementation of one
class in terms of another's. Reuse by subclassing is often referred to as white-box reuse. The term "whitebox"
refers to visibility: With inheritance, the internals of parent classes are often visible to subclasses.
Object composition is an alternative to class inheritance. Here, new functionality is obtained by assembling
or composing objects to get more complex functionality. Object composition requires that the objects being
composed have well-defined interfaces. This style of reuse is called black-box reuse, because no internal
details of objects are visible. Objects appear only as "black boxes."
Inheritance and composition each have their advantages and disadvantages. Class inheritance is defined
statically at compile-time and is straightforward to use, since it's supported directly by the programming
language. Class inheritance also makes it easier to modify the implementation being reused. When a
subclass overrides some but not all operations, it can affect the operations it inherits as well, assuming they
call the overridden operations.
But class inheritance has some disadvantages, too. First, you can't change the implementations inherited
from parent classes at run-time, because inheritance is defined at compile-time. Second, and generally
worse, parent classes often define at least part of their subclasses' physical representation. Because
inheritance exposes a subclass to details of its parent's implementation, it's often said that "inheritance
breaks encapsulation" [Sny86]. The implementation of a subclass becomes so bound up with the
implementation of its parent class that any change in the parent's implementation will force the subclass to
change.
Implementation dependencies can cause problems when you're trying to reuse a subclass. Should any aspect
of the inherited implementation not be appropriate for new problem domains, the parent class must be
rewritten or replaced by something more appropriate. This dependency limits flexibility and ultimately
reusability. One cure for this is to inherit only from abstract classes, since they usually provide little or no
implementation.
Object composition is defined dynamically at run-time through objects acquiring references to other objects.
Composition requires objects to respect each others' interfaces, which in turn requires carefully designed
interfaces that don't stop you from using one object with many others. But there is a payoff. Because objects
are accessed solely through their interfaces, we don't break encapsulation. Any object can be replaced at runtime
by another as long as it has the same type. Moreover, because an object's implementation will be
written in terms of object interfaces, there are substantially fewer implementation dependencies.
Object composition has another effect on system design. Favoring object composition over class inheritance
helps you keep each class encapsulated and focused on one task. Your classes and class hierarchies will
remain small and will be less likely to grow into unmanageable monsters. On the other hand, a design based
on object composition will have more objects (if fewer classes), and the system's behavior will depend on
their interrelationships instead of being defined in one class.
分享到:
相关推荐
这倒也符合 GoF 的《Design Patterns-Elements of Reusable of Object-Oriented Software》书中的一个建议:Favor object composition over class inheritance,即优先使用对象组合而不是继承。 PML 中的对象...
在面向对象编程中,有两种重要的设计原则:Program to an interface, not an implementation和Favor object composition over class inheritance。前者强调使用者不需要知道数据类型、结构、算法的细节,只需要知道...
- 继承和组合的使用场景选择,尽量减少浅继承,提倡"favor object composition over class inheritance"。 - 使用const和引用参数,提高程序安全性。 - 设计模式:单例、工厂、观察者等设计模式在面试中也常被...
Classes Inheritance Multiple Inheritance Interfaces Operator Overloading Access Control Declaration Order Write Short Functions Google-Specific Magic Smart Pointers cpplint Other C++ Features ...
优先使用组合而非继承 (Favor Composition Over Inheritance) 在设计类结构时,应优先考虑使用组合(has-a)关系,而不是继承(is-a)。继承可能导致类层次过于复杂,而组合则更加灵活,可以更自由地组合对象的功能...