機能java item 18
24468 ワード
継承するより複合語を使うほうがいいです。
継承(Inherit)
:継承クラス拡張他のクラスの実装
親クラスは、リリースごとに内部実装が異なる場合があります.その影響は、1行のコードに触れていない子クラスでエラーが発生する可能性があります.
->メソッド呼び出しとは異なり、継承はカプセルを引き裂きます.public class InstrumentHashSet<E> extends HashSet<E>{
//추가된 원소의 수
private int addCount = 0;
public InstrumentHashSet(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 AddCount() {
return addCount;
}
}
InstrumentedHashSet<String> s = new InstrumentedHashSet<>();
s.addAll(List.of("틱", "탁탁", "펑"));
addCount에 3을 더한 후 HashSet의 addAll 호출,
HashSet의 addAll은 각 원소를 add 메서드를 호출해서 추가하는데,
이때 불리는 add는 InstrumentedHashSet에서 재정의한 메서드.
-> addCount에 값이 중복해서 더해져, 최종값이 6으로 늘어난 것.
addAll로 추가한 원소 하나당 2씩 증가.
親に新しいメソッドを追加する方法
幸いなことに、サブクラスに追加されたメソッドがスキーマと同じで、戻りタイプが異なる場合はコンパイルできません.
妙策.
既存のクラスを拡張するよりも、新しいクラスを作成しprivateフィールドを使用して既存のクラスのインスタンスを参照します.
[位置]
:既存のクラスが新しいクラスのコンポーネントとして使用されていることを示します.ここで、これらの設計を複合(組合せ;構成)と呼ぶ.
新しいクラスのインスタンスメソッド(privateフィールドとして参照)は、既存のクラスの対応メソッドを呼び出して結果を返します.
この方式を転送と呼ぶ.
新しいクラスのメソッドを転送メソッドと呼びます.
上記のコードの1つは、集合クラス自体であり、もう1つは、転送メカニズムのみによって実現される再利用可能な転送クラスの例である.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 class ForwardingSet<E> implements Set<E> {
private final Set<E> s;
public ForwardingSet(Set<E> s) { this.s = s; }
public void claer() { 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<?> 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(); }
}
HashSetのすべての機能を定義したSetインタフェースを用いて設計した.
硬くて柔らかい.
具体的にはSetインタフェースを実現した.
Setのインスタンスを引数として受信するコンストラクション関数を提供します.
任意のSet計測機能を追加し,新しいSetがクラスのコアとなるようにする.
継承方法:
各特定のクラスを個別に拡張する必要があります.
サポートする親クラスごとに作成者を個別に定義します.
Rapperクラス:
InstrumentedSetなどのクラスは、他のSetインスタンスが含まれていることを示します.
Decoratorモード:
測定機能を他のスイートに追加
委任(委任):
コンビネーションと伝達のコンビネーション.
(Rapperオブジェクトが内部オブジェクトに自分の参照を渡す場合のみ)
Rapperクラスはほとんど欠点がなく、
これはコールバックフレームワークと一致しないことに注意してください.
public class InstrumentHashSet<E> extends HashSet<E>{
//추가된 원소의 수
private int addCount = 0;
public InstrumentHashSet(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 AddCount() {
return addCount;
}
}
InstrumentedHashSet<String> s = new InstrumentedHashSet<>();
s.addAll(List.of("틱", "탁탁", "펑"));
addCount에 3을 더한 후 HashSet의 addAll 호출,
HashSet의 addAll은 각 원소를 add 메서드를 호출해서 추가하는데,
이때 불리는 add는 InstrumentedHashSet에서 재정의한 메서드.
-> addCount에 값이 중복해서 더해져, 최종값이 6으로 늘어난 것.
addAll로 추가한 원소 하나당 2씩 증가.
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 class ForwardingSet<E> implements Set<E> {
private final Set<E> s;
public ForwardingSet(Set<E> s) { this.s = s; }
public void claer() { 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<?> 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(); }
}
自分のリファレンスを他のオブジェクトに渡して、次回の呼び出し(コールバック)で使用します.
自身(this)への参照をスキップし、コールバック時にRapperではなく内部オブジェクトを呼び出します.
継承は、子が親の真の子タイプである場合に使用する必要があります.
クラスAは、クラスBがクラスAとis-aの関係である場合にのみ継承される.
「Bって本当にAなの?」
「No」の場合、Aはprivateインスタンスとして使用されます.
Aとは異なるAPIを提供する必要がある.
すなわち、AはBの必須コンポーネントxの実施方法の1つである.
欠陥を補うために新しいAPIを設計することができるが.
継承親APIの欠陥への継承
Collection c
https://installed.tistory.com/entry/%EC%9E%90%EB%A3%8C%EA%B5%AC%EC%A1%B0-ArrayList-%EC%A0%9C%EB%84%A4%EB%A6%AD-%ED%81%B4%EB%9E%98%EC%8A%A4-%ED%99%95%EC%A0%95for-%EB%AC%B8#:~:text=1.%20ArrayList%20%28Collection%3C%3F%20extends%20E%3E%20c%29%20-%20Collection%3C%3F,c%20%3A%20E%ED%83%80%EC%9E%85%EC%9D%98%20%ED%81%B4%EB%9E%98%EC%8A%A4%EC%9D%B4%EA%B1%B0%EB%82%98%20E%ED%83%80%EC%9E%85%EC%9D%98%20%EB%B6%80%EB%AA%A8%ED%81%B4%EB%9E%98%EC%8A%A4%EA%B0%80%20%EC%A0%9C%EB%84%A4%EB%A6%AD%ED%83%80%EC%9E%85%EC%9C%BC%EB%A1%9C%20%EC%A7%80%EC%A0%95%EB%90%A8
ジェニーリック/E型/T型
https://velog.io/@ayoung0073/java-generic
フレーム、コールバック
https://purple-wood-lights.tistory.com/6
スタック
https://doorrock.tistory.com/5
Reference
この問題について(機能java item 18), 我々は、より多くの情報をここで見つけました https://velog.io/@jiwon709/이펙티브자바-item18テキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol