《Effective Java 第三版》——第二章 创建和销毁对象
《Effective Java 第三版》——第三章 所有对象都通用的方法

package effectivejava.chapter4.item18; import java.util.*; // Broken - Inappropriate use of inheritance! (Page 87) public class InstrumentedHashSet<E> extends HashSet<E> { // The number of attempted element insertions private int addCount = 0; public InstrumentedHashSet() { } 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() { return addCount; } public static void main(String[] args) { InstrumentedHashSet<String> s = new InstrumentedHashSet<>(); s.addAll(List.of("Snap", "Crackle", "Pop")); System.out.println(s.getAddCount()); } } //输出:6
应该加个语法糖自动生成 转发类?
==> Guava 中文教程:https://www.kancloud.cn/wizardforcel/guava-tutorial/106936
package effectivejava.chapter4.item18; import java.util.*; // Reusable forwarding class (Page 90) 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(); } }
package effectivejava.chapter4.item18; import java.util.*; // Wrapper class - uses composition in place of inheritance (Page 90) 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() { return addCount; } public static void main(String[] args) { InstrumentedSet<String> s = new InstrumentedSet<>(new HashSet<>()); s.addAll(List.of("Snap", "Crackle", "Pop")); System.out.println(s.getAddCount()); } } //输出:3
https://github.com/google/guava/blob/master/guava/src/com/google/common/collect/ForwardingList.java
>>
《骨架实现类》
Java骨架类
实现 Skeletal Implementation 模式,主要分三步走:
-
创建一个接口,即共同协议 (有些时候,只为了解决类无法多继承的问题,这个协议也可以不用)。
-
创建一个抽象类,并实现 1 所创建的接口,然后,把通用行为写在里面,并抽出需要子类自己定制的抽象方法。(听起来,跟模板类差不多)
-
在本该继承这个抽象类的子类里面,创建一个私有内部类,在这个私有内部类里面,重写,填充抽象方法。然后,由这个子类,扩展 1 所说的接口,然后,1 所说的接口所带的方法实现,代理给这个私有内部类去做。
要完成骨架实现:
-
创建接口。
-
创建抽象类来实现该接口,并实现公共方法。
-
在子类中创建一个私有内部类,继承抽象类。现在把外部调用委托给抽象类,该类可以在使用通用方法同时继承和实现任何接口。
“服从于”另外一个类