16th: Compound takes precedence over inheritance

Source: Internet
Author: User
Tags addall

Inheritance is a powerful way to implement code reuse, but improper use can cause software to become brittle. It is very safe to use inheritance inside a package, and subclasses and superclass implementations are under the control of the same programmer. Inheritance is also very safe for classes that are designed specifically for inheritance and that have good documentation descriptions. However, you should be very careful about inheritance that spans the bounds of the package. "Inheritance" here refers specifically to a class extending another class.

 Public classInstrumentedhashset<e>extendsHashset<e> {    Private intAddcount = 0;  PublicInstrumentedhashset () {} PublicInstrumentedhashset (intInitcap,floatloadfactor) {        Super(Initcap, loadfactor); } @Override Public BooleanAdd (e e) {Addcount++; return Super. Add (e); } @Override Public BooleanAddAll (collection<?extendsE>c) {Addcount+=c.size (); return Super. AddAll (c); }         Public intGetaddcount () {returnAddcount; }         Public Static voidMain (string[] args) {Instrumentedhashset<String> s =NewInstrumentedhashset<string>(); S.addall (Arrays.aslist ("S", "a", "P"));    System.out.println (S.getaddcount ()); }}

Consider the hashset that provides the count function above. We want the result to be 3, but the result is 6, because the AddAll method is implemented based on the Add method, and the Instrumentedhashset AddAll method first Addcount plus 3, Then Super.addall calls HashSet's AddAll method, and AddAll calls to the Instrumentedhashset-overridden Add method, each element is called once and adds 3 to the Addcount, and the result is 6.

As long as the AddAll method is removed to correct the problem, although this class can work properly, but the HashSet AddAll method is to implement the details, not the commitment, means that the addall implementation of the future release of the version will remain unchanged.

A slightly better approach is to override the AddAll method to iterate over the specified collection and call the Add method once for each element, which guarantees the correct result, but this method is powerless to access the private domain of the superclass.

Override every method of adding elements to the superclass, and if the superclass adds a new method of adding elements later, there may be an "illegal element" added to the collection.

Instead of extending an existing class, adding a private domain to the new class that references an instance of an existing class avoids the previously mentioned problem, which is called "compositing," because the existing class becomes a component of the new class, and each instance method in the new class can invoke the corresponding method in the existing class instance that is contained. and returns the result of it.

 Public classForwardingset<e>ImplementsSet<e> {    PrivateSet<e>s;  PublicForwardingset (set<e>s) { This. S =s; }     Public voidClear () {s.clear (); }     Public Booleancontain (Object o) {returns.contains (o); }     Public BooleanIsEmpty () {returnS.isempty (); }     Public intsize () {returns.size (); }     PublicIterator<e>iterator () {returnS.iterator (); }     Public BooleanAdd (e e) {returnS.add (e); }     Public BooleanRemove (Object o) {returnS.remove (o); }     Public BooleanContainsall (collection<?>c) {returnS.containsall (c); }     Public BooleanAddAll (collection<?extendsE>c) {returnS.addall (c); }         Public BooleanRetainall (collection<?>c) {returnS.retainall (c); }     Publicobject[] ToArray () {returnS.toarray (); }     Public Booleanequals (Object o) {returns.equals (o); }     Public inthashcode () {returnS.hashcode (); }     PublicString toString () {returns.tostring (); } @Override Public Booleancontains (Object o) {//TODO auto-generated Method Stub        return false; } @Override Public<T>t[] ToArray (t[] a) {//TODO auto-generated Method Stub        return NULL; } @Override Public BooleanRemoveAll (collection<?>c) {returnS.removeall (c); }      }

 Public classInstrumentedset<e>extendsForwardingset<e> {    Private intAddcount = 0;  PublicInstrumentedset (set<e>s) {Super(s); }         Public BooleanAdd (e e) {Addcount++; return Super. Add (e); }         Public BooleanAddAll (collection<?extendsE>c) {Addcount+=c.size (); return Super. AddAll (c); }         Public intGetaddcount () {returnAddcount; }}

Forwardingset, as a forwarding class, has a set instance variable, and Instrumentedset overrides the Add and AddAll methods to implement the Count function.

16th: Compound takes precedence over inheritance

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.