親から子メソッドを呼び出す理由
11119 ワード
学習の背景
効果java単品18。継承するより複合語を使うほうがいいです。には有名な例がある. public class InstrumentedHashSet<E> extends HashSet<E> {
// 추가된 원소의 수
private int addCount = 0;
public InstrumentedHashSet() {
}
@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;
}
}
InstrumentedHashSet<String> languages = new InstrumentedHashSet<>();
languages.addAll(Arrays.asList("Java", "Ruby", "Scala"));
HashSetpublic class HashSet<E>
extends AbstractSet<E> ... {
...
}
AbstractSetpublic abstract class AbstractSet<E> extends AbstractCollection<E> ... {
...
}
AbstractCollectionpublic abstract class AbstractCollection<E> implements Collection<E> {
...
public boolean addAll(Collection<? extends E> c) {
boolean modified = false;
for (E e : c)
if (add(e))
modified = true;
return modified;
}
}
上記のコードを実行すると、言語でgetAddCount
を使用すると、一般的に3が表示されます.しかし、実際には6です.これは、HashSet
のaddAll
において、add
が重複文によってアイテム数に従って呼び出されるためである.
ここで疑問が出てきました.親クラスでメソッドを定義した場合は、親クラスのメソッドを使用する必要があります.なぜ子クラスのメソッドを呼び出すのですか?
勉強する
メソッドナビゲーション
オブジェクト向けのシステムでは,多形性により,どのような方法を実行するかを動的に決定する.このとき、実行するメソッドを選択するにはルールがあります.
public class InstrumentedHashSet<E> extends HashSet<E> {
// 추가된 원소의 수
private int addCount = 0;
public InstrumentedHashSet() {
}
@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;
}
}
InstrumentedHashSet<String> languages = new InstrumentedHashSet<>();
languages.addAll(Arrays.asList("Java", "Ruby", "Scala"));
public class HashSet<E>
extends AbstractSet<E> ... {
...
}
public abstract class AbstractSet<E> extends AbstractCollection<E> ... {
...
}
public abstract class AbstractCollection<E> implements Collection<E> {
...
public boolean addAll(Collection<? extends E> c) {
boolean modified = false;
for (E e : c)
if (add(e))
modified = true;
return modified;
}
}
メソッドナビゲーション
オブジェクト向けのシステムでは,多形性により,どのような方法を実行するかを動的に決定する.このとき、実行するメソッドを選択するにはルールがあります.
self (this)
上記の手順を実行する前に、オブジェクトがメッセージを受信すると、コンパイラはself参照という一時変数を自動的に生成し、そのメッセージを受信したオブジェクトに動作を指示します.
静的タイプ言語に属するJavaでは,C++でthis,動的タイプ言語ではselfが主に用いられる.
コードからメッセージを受信するオブジェクトは
languages
です.selfは、InstrumentedHashSet
を指すように設定された例を参照する.languages
にaddAll()
情報を送信する.languages
は、独自のクラスを生成するInstrumentedHashSet
でaddAll()
を実行し、コードからsuper.addAll()
がある.だから祖先階級の中で探求するために、直接偉人HashSet
に行きます.HashSet
にはaddAll
を処理する適切な方法がないため、祖先の等級に従って、AbstractCollectionでaddAll()
が見つかった.しかし、ここではadd()
を転送する文に遭遇します.メソッドナビゲーションはself参照が指すオブジェクトから開始します.従って、このときInstrumentedHashSet
のadd()
が存在するので、InstrumentedHashSet
の方法が用いられる.結果
最初は、親が親で定義されたメソッドではなく、子のメソッドを使用する理由が理解できませんでした.言葉で決まっているだけでしょう.しかし、このようにルールを決めるには原理があるに違いない.今は原理が分かった.
リファレンス
オブジェクト12章-多形性
Reference
この問題について(親から子メソッドを呼び出す理由), 我々は、より多くの情報をここで見つけました
https://velog.io/@injoon2019/왜-조상-클래스에서-자손-클래스-메서드를-호출하나
テキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol
オブジェクト12章-多形性
Reference
この問題について(親から子メソッドを呼び出す理由), 我々は、より多くの情報をここで見つけました https://velog.io/@injoon2019/왜-조상-클래스에서-자손-클래스-메서드를-호출하나テキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol