Read the Chinese version of objective Java (15)
Article 21: combination takes precedence over inheritance
Inheritance is implementationCodePowerful means of reuse, But improper use of inheritance can lead to vulnerable software.
- It is safe to use inheritance in a package, because the subclass and the super class are in the sameProgramUnder the control of members.
- Inheritance is also safe for classes designed specifically for inheritance and well documented.
- It is very dangerous to inherit the cross-hop packet boundary of a common concret class.
Different from method calls, inheritance breaks the encapsulation. A subclass depends on the implementation details of special functions in its super class. Sub-classes may be broken if the sub-classes are changed.
- Self-use, that is, there is a call relationship between the implementation of different public methods in the super class. When the subclass modifies these methods, it often leads to the vulnerability of the subclass.
- A superclass adds a new method to its subsequent methods. If the subclass cannot rewrite these methods in time, abnormal data or operations may occur.
- After the subclass inherits the superclass, a new method is added. When the superclass also add methods with the same prototype features in the new version, problems may occur.
There is one way to avoid all the above problems: the new class is not to expand an existing class, but to set a private domain that references an instance of this existing class. This design is called composition )". Each instance method in the new class can call the corresponding method of the existing class instance to be included, and return its result, that is, "forwarding method )". Such classes are relatively stable, which does not depend on the implementation details of existing classes. An instance of a class encapsulates the implementation of another class, and the class of the former is called the Wrapper class ).
Let's look at an example:
// Wrapper class-uses composition in place of Inheritance
Public class instrumentedset implements set {
Private final set S;
Private int addcount = 0;
Public instrumentedset (set S ){
This. S = s;
}
Public Boolean add (Object O ){
Addcount ++;
Return S. Add ();
}
Public Boolean addall (collection C ){
Addcount + = C. Size ();
Return S. addall (C );
}
Public int getaddcount (){
Return addcount;
}
// Forwarding Methods
Public void clear () {S. Clear ();}
Public Boolean contains (Object O) {return S. Contains (o );}
Public Boolean isempty () {return S. isempty ();}
Public int size () {return S. Size ();}
....
Public String tostring () {return S. tostring ();}
}
In the preceding example, the instrumentedset class modifies the set class and adds the counting feature. Sometimes, the combination of the composite and forwarding technologies is mistakenly referred to as "delegation". From a technical perspective, this is not a delegate, unless the packaging object passes itself to a encapsulated object.
The packaging class has almost no disadvantages. It should be noted that the packaging class is not suitable for the callback framework. In the callback framework, an object Passes its reference to other objects so that it can be called back in the future. When it is encapsulated, it does not know the situation of the external packaging object, therefore, when it passes a reference (this) pointing to itself, it will cause the callback to bypass the external packaging object. This is called the self problem.
Inheritance is appropriate only when the subclass is actually a subtype of the super class. That is, the relationship between the two is-. Java platforms also violate this rule: for example, the stack is not a vector, So Vector should not be extended; the attribute list is not a hash, so properties should not be extended with hashtable. When deciding whether to use composite or extension, check whether the API of the class to be extended has any defects. If you are willing to spread these defects to your own API, use inheritance, otherwise, you can use a combination to design a new API.
Posted by Hilton at February 14,200 4 pm | trackback