Effective Java 16 Favor composition over inheritance

Inheritance disadvantage

Unlike method invocation, inheritance violates encapsulation. Since you don't know the super class implementation which may involve some unpredictable calling between different methods of super class. And it is difficult to maintain the subclass when there is a change of the super class.

   

Be careful with the interaction between inner methods of the superclass. Here is the demo.

   

package com.effectivejava.classinterface;

   

import java.util.Collection;

import java.util.Set;

   

/**

* @author Kaibo

*

*/

// Wrapper class - uses composition in place of inheritance

public 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() {

/* If you directly extends one implementation such as HashSet<E> of the Set<E> interface you will get the wrong addCount since the addAll method invoke the add method internally which has been override by your sub class.

*/

return addCount;

}

}

   

/**

* Implementation of prefer to composite to inherence.

*/

package com.effectivejava.classinterface;

   

import java.util.Collection;

import java.util.Iterator;

import java.util.Set;

   

/**

* @author Kaibo

*

*/

// Reusable forwarding class

public class ForwardingSet<E> implements Set<E> {

private final Set<E> s;

   

public ForwardingSet(Set<E> s) {

this.s = s;

}

   

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 Iterator<E> iterator() {

return s.iterator();

}

   

public boolean add(E e) {

return s.add(e);

}

   

public boolean remove(Object o) {

return s.remove(o);

}

   

public boolean containsAll(Collection<?> c) {

return s.containsAll(c);

}

   

public boolean addAll(Collection<? extends E> c) {

return s.addAll(c);

}

   

public boolean removeAll(Collection<?> c) {

return s.removeAll(c);

}

   

public boolean retainAll(Collection<?> c) {

return s.retainAll(c);

}

   

public Object[] toArray() {

return s.toArray();

}

   

public <T> T[] toArray(T[] a) {

return s.toArray(a);

}

   

@Override

public boolean equals(Object o) {

return s.equals(o);

}

   

@Override

public int hashCode() {

return s.hashCode();

}

   

@Override

public String toString() {

return s.toString();

}

}

   

Wrapper class (Composite) disadvantage

Wrapper classes are not suited for use in callback frameworks, wherein objects pass self-references to other objects for subsequent invocations ("callbacks").

   

To avoid the method invoke subclass's overrided version

You can eliminate a class's self-use of overridable methods mechanically, without changing its behavior. Move the body of each overridable method to a private "helper method" and have each overridable method invoke its private helper method. Then replace each self-use of an overridable method with a direct invocation of the overridable method's private helper method.

转载于:https://www.cnblogs.com/haokaibo/p/favor-composition-over-inheritance.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值