Effective Java Learning--16th: compound takes precedence over inheritance

Source: Internet
Author: User
Tags addall

In the course of system analysis and design, one of the Kings kept on emphasizing that ISA (is a principle). All know that inheritance is a major element of object-oriented, but where to use the compound where the use of inheritance, in fact, there are fastidious.

Can be simply summed up with the ISA principle. There is a certain functional class, we have to expand its function, in the end is the use of composite or inheritance it? When the relationship between the new class and the old class is a dependency, that is, the cat is an animal,english book is a book, we take precedence over inheritance; When the new class is one of the components of the old class, hand is a part of the BODY,JIANGSU is a parts Of China, we prefer to use compounding.

The reasons are as follows: when we want to extend a class, especially a class that someone else has written, a class library, we tend to be concerned only with the functionality of a single API, not his implementation, but one problem is that the methods of the same class may be directly connected, and the implementation of one method may depend on another. , which means that when we invoke a method that we want to manipulate, inheritance implicitly calls another method, which can be problematic.

The classic example is the intrinsic connection of add () and AddAll () in set.
Requirements: Create a new collection class, maintain a addcount variable, record how many new values have been added. It is implemented by inheritance and composition respectively.
First Look at inheritance:
Myset.java

Package Cczu.edu.test2;import Java.util.collection;import Java.util.HashSet; Public  class MySet<e> extends HashSet<e>{    Private intAddcount =0; PublicMySet () {} @Override Public BooleanAdd (e e) {addcount++;return Super. Add (e); } @Override Public BooleanAddAll (collection<? extends e> c) {addcount + = C.size ();return Super. AddAll (c); } Public intGetaddcount () {returnAddcount; }}

Test

@Test Public voidTest1 () {MySet<String> Set = NewMySet<String>();List<String> List = NewArrayList<String>();List.Add"ABC");List.Add"Def");List.Add"Ghi");Set.AddAll (List); System.Out.printlnSet.Getaddcount ());//the ans is 6}

Because, in HashSet's AddAll () implementation, it is the loop that calls the Add () method, so it causes 3*2. Of course you can also rewrite the AddAll () method, but this loses the meaning of inheritance.

Using comps:
Forwardingset.java

Package Cczu.edu.test2;import Java.util.collection;import Java.util.hashset;import java.util.iterator;import Java.util.Set; Public classForwardingset<e> implements Set<e> {PrivateFinal set<e> S; Public Forwardingset(set<e> s) { This. s = s; } Public Forwardingset(){ This. S =NewHashset<e> (); } @Override Public int size() {returnS.size (); } @Override PublicBooleanIsEmpty() {returnS.isempty (); } @Override PublicBooleancontains(Object o) {returnS.contains (o); } @Override PublicIterator<e>iterator() {returnS.iterator (); } @Override PublicObject[]ToArray() {returnS.toarray (); } @Override Public<T> t[]ToArray(t[] a) {returnS.toarray (a); } @Override PublicBooleanAdd(e) {returnS.add (e); } @Override PublicBooleanRemove(Object o) {returnS.remove (o); } @Override PublicBooleanContainsall(collection<?> c) {returnS.containsall (c); } @Override PublicBooleanAddAll(collection<? extends e> c) {//TODO auto-generated method stub        return false; } @Override PublicBooleanRetainall(collection<?> c) {returnS.retainall (c); } @Override PublicBooleanRemoveAll(collection<?> c) {returnS.removeall (c); } @Override Public void Clear() {s.clear (); }}

Myset2.java

Package Cczu.edu.test2;import java.util.Collection; Public  class MySet2<e> extends forwardingset<e>{     Private intAddcount =0; @Override Public BooleanAdd (e e) {addcount++;return Super. Add (e); } @Override Public BooleanAddAll (collection<? extends e> c) {addcount + = C.size ();return Super. AddAll (c); } Public intGetaddcount () {returnAddcount; }}

Test

@Test Public voidTest2 () {MySet2<String> Set = NewMySet2<String>();List<String> List = NewArrayList<String>();List.Add"ABC");List.Add"Def");List.Add"Ghi");Set.AddAll (List); System.Out.printlnSet.Getaddcount ());//the ans is 3}

Adding a Forwardingset.java function is simply to implement forwarding.

Looking back, the compound can wrap the old class completely so that we don't have to focus on the implementation of the old class, at the same time achieve the effect of calling the old class method, avoiding the connection between the old class methods, and then adding the old class if there are other permissions problems, the compound can also hide the flaw.

Self-summary: In fact, design patterns such as proxy mode, adapter mode, decorator mode, and inheritance, composite are some connection, so that I have a little confusion, after all, design patterns are dead, thought is alive.

Effective Java Learning--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.