1. Disadvantages of inheritance

  • Inheritance is not easy to control, and when used improperly, software can be very fragile, especially when inheriting classes that are not in the same package.
  • Inheritance breaks the encapsulation of the parent class, and sometimes the internal implementation of the parent class changes, which may cause the subclass to be broken.

For example, suppose we have a program that uses HashSet. To see how many elements it has added since it was created, we extend the HashSet by inheritance, overriding the add and addAll methods.


public class InstrumentedHashSet<E> extends HashSet<E> {
  private int addCount = 0;

  public InstrumentedHashSet(a) {}

  public InstrumentedHashSet(int initCap, float loadFactor) {
    super(initCap, loadFactor);
  }

  @Override
  public boolean add(E e) {
    addCount ++;
    return super.add(e);
  }

  @Override
  public boolean addAll(Collection<? extends E> c) {
    addCount += c.size();
    return super.addAll(c);
  }

  public int getAddCount(a) {
    returnaddCount; }}Copy the code

This code looks fine. If we execute the following program, we expect getAddCount to return 3, but it actually returns 6.

InstrumentedHashSet<String> s = new InstrumentedHashSet<String>();
s.addAll(Arrays.asList("Snap"."Crackle"."Pop"));
System.out.println(s.getAddCount());
Copy the code

What went wrong?

Inside a HashSet, the addAll method is implemented based on the Add method, even if the HashSet documentation does not specify this detail, which is reasonable. So the addAll method in the InstrumentedHashSet first increments the addCount by 3 and then calls the addAll implementation of the HashSet with super.addall (). In this implementation, was InstrumentedHashSet covered calls the add method, each element call once, the three again adds 1 to addCount respectively, so the total increased by 6.

Therefore, extending a class with inheritance is dangerous, and the implementation of the parent class can easily affect the correctness of the subclass. Composition over inheritance tells us that instead of extending an existing class, we can add a private field to a new class that references an instance of an existing class. This design is called Composition. = =

What is getting back together

Composition is adding a private field to your class, referencing an instance of the class, and making the referenced class a component of the referenced class.

What is fowarding: Each instance method in a new class can call a corresponding method from an contained existing class instance and return results.

3. Use the compound principle

  • Design a forward class for classes that you want to inherit
  • Inheritor forward class
  • Override the method you want to override, or add the method you want to add.

4. Use composite examples

Extending a class using composition requires implementing two parts: == New class == and == reusable forwarding class ==. The forward class is used to forward all method calls to the private domain. The resulting class is robust and does not depend on the implementation details of the existing class. Take a look at the following example.

//Wrapper class - use composition in place of inheritancepublic class InstrumentedSet<E> extends ForwardingSet<E>{

    private int addCount = 0;
    
    public InstrumentedSet(Set<E> s) {
        super(s);
    }
    
    @Override
    public boolean add(E e) {
        addCount ++;
        return super.add(e);
    }
    
    @Override
    public boolean addAll(Collection<? extends E> c) {
        addCount += c.size();
        return super.addAll(c);
    }
    
    public int getAddCount(a) {
        return addCount;
    }}
//Reusable forwarding classclass ForwardingSet<E> implements Set<E> {
    
    private final Set<E> s;
    
    public ForwardingSet(Set<E> s) {this.s = s; }@Override
    public int size(a) {returns.size(); }@Override
    public boolean isEmpty(a) {returns.isEmpty(); }@Override
    public boolean contains(Object o) {returns.contains(o); }@Override
    public Iterator<E> iterator(a) {returns.iterator(); }@Override
    public Object[] toArray() {returns.toArray(); }@Override
    public <T> T[] toArray(T[] a) {returns.toArray(a); }@Override
    public boolean add(E e) {returns.add(e); }@Override
    public boolean remove(Object o) {returns.remove(o); }@Override
    public boolean containsAll(Collection
        c) {returns.containsAll(c); }@Override
    public boolean addAll(Collection<? extends E> c) {returns.addAll(c); }@Override
    public boolean retainAll(Collection
        c) {returns.retainAll(c); }@Override
    public boolean removeAll(Collection
        c) {returns.retainAll(c); }@Override
    public void clear(a) {s.clear();}
    }
Copy the code

InstrumentedSet InstrumentedSet InstrumentedSet InstrumentedSet InstrumentedSet InstrumentedSet InstrumentedSet InstrumentedSet An additional benefit is that the wrapper class InstrumentedSet can be used to package any Set implementation, which has a wider applicability.

For example,

Set<Date> s = new InstrumentedSet<Date>(new TreeSet<Date>(cmp));
Set<E> s2 = new InstrumentedSet<E>(new HashSet<E>(capacity));
Copy the code

5. Disadvantages of compounding

Wrapper classes do not work well in callback frameworks, where objects pass references to themselves to other objects for subsequent calls. Because the wrapped object is unaware of the enclosing object, it passes a reference to itself (this), and the callback avoids the enclosing object. This is called the SELF problem.

6. Summary

Only when a subclass and a father-son relationship exists between the superclass, even so, = = if subclasses and superclass exist different package, and the superclass isn’t designed to inherit, the inheritance will lead to vulnerabilities, composite and turn forwarding mechanism can be used in place of the inheritance, especially when there is the appropriate interface can realize wrapper classes. Wrapper classes are not only more robust than subclasses, they are also more powerful.

7. References

www.jianshu.com/p/4fd034505…

“Effective Java”

www.cnblogs.com/jjfan0327/p…

Pay attention to the public account “Programmer interview”

Reply to “interview” to get interview package!!

This public account to share their own from programmer xiao Bai to experience spring recruitment autumn recruitment cut more than 10 offer interview written test experience, including [Java], [operating system], [computer network], [design mode], [data structure and algorithm], [Dacheng face by], [database] look forward to you join!!

1. Computer network —- Three times shake hands four times wave hands

2. Dream come true —– Project self-introduction

Here are the design patterns you asked for

4. Shocked! Check out this programmer interview manual!!

5. Teach you the interview “Profile” word for word

6. Nearly 30 interviews shared