独自のAndroidカスタムクラスを作成するとき、そのネイティブクラスをextend
します。その後、ベースメソッドをオーバーライドするときは、常にsuper()
メソッドを呼び出します、常にonCreate
、onStop
などで行うように.
そして、最初からAndroidチームはメソッドのオーバーライドごとに常にsuper
を呼び出すように勧めていたので、これだと思いました。
しかし、多くの本では、私より経験豊富な開発者が、super
の呼び出しを省略していることがよくわかります。知識不足として。たとえば、この基本的な [〜#〜] sax [〜#〜] パーサークラスを見てください。super
はstartElement
、characters
で省略されていますおよびendElement
:
public class SAXParser extends DefaultHandler{
public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
if(qName.equalsIgnoreCase("XXY")) {
//do something
}
}
public void characters(char[] ch, int start, int length) throws SAXException {
//do something
}
public void endElement(String uri, String localName, String qName) throws SAXException {
if(qName.equalsIgnoreCase("XXY")) {
//do something
}else () {
//do something
}
}
}
Eclipseまたは他のIDEを介してオーバーライドメソッドを作成しようとすると、super
は常に自動化プロセスの一部として作成されます。
これは単純な例です。書籍は同様のコードでいっぱいです。
super
を呼び出さなければならないとき、および呼び出しを省略することができるときを、彼らはどのようにして知っていますか?
PS。この特定の例にバインドしないでください。これは、多くの例からランダムに選んだ例にすぎません。
(これは初心者の質問のように聞こえるかもしれませんが、私は本当に混乱しています。)
super
メソッドを呼び出すことにより、メソッドの動作をオーバーライドするのではなく、拡張する 。
super
を呼び出すと、拡張するクラスがそのメソッドに対して定義したロジックが実行されます。メソッドのオーバーライドでsuper
の実装を呼び出すときに重要になる可能性があることを考慮してください。例えば:
_public class A {
public void save() {
// Perform save logic
}
}
public class B extends A {
private Object b;
@Override
public void save() {
super.save(); // Performs the save logic for A
save(b); // Perform additional save logic
}
}
_
B.save()
を呼び出すと、A
とB
の両方に対して、この特定の順序でsave()
ロジックが実行されます。 super.save()
内でB.save()
を呼び出さなかった場合、A.save()
は呼び出されません。そして、super.save()
の後にsave(b)
を呼び出した場合、A.save()
は後でB.save()
で効果的に実行されます。
overridesuper
の動作(つまり、その実装を完全に無視し、すべて自分で提供する)が必要な場合は、super
を呼び出してはいけません。
提供するSAXParser
の例では、これらのメソッドのDefaultHandler
の- implementations は空であるため、サブクラスがそれらをオーバーライドして、それらのメソッドの動作を提供できます。このメソッドの javadoc でもこれが指摘されています。
_public void startElement (String uri, String localName,
String qName, Attributes attributes) throws SAXException {
// no op
}
_
_@barsju
_がコメントで指摘したように、IDEによって生成されたコードのsuper()
のデフォルト呼び出しについて、各コンストラクターにはsuper()
の暗黙的な呼び出しがあります(たとえtをコードに記述します)、つまり、そのコンテキストでは、super
のデフォルトコンストラクターの呼び出しを意味します。 IDE
は単にそれを書き留めますが、削除した場合にも呼び出されます。また、コンストラクターを実装する場合、super()
または引数を持つそのバリアント(つまりsuper(x,y,z)
)は最初にしか呼び出せないことに注意してくださいメソッドの。
Superを呼び出す必要があるときと、それを呼び出すことを省略できるときを、彼らはどのようにして知るのですか?
通常、特別なAPIメソッドが基盤となるフレームワークコンテキストライフサイクルに重要な意味を持っている場合、 Activity.onCreate()
API documentation 。さらに、APIが堅牢な設計に従っている場合、プロジェクトのコンパイル時にコンシューマ開発者に警告するためにいくつかの例外をスローし、実行時にフォールトが生成されないことを確認する必要があります。
これがAPIドキュメントに明示的に記載されていない場合、コンシューマー開発者は、APIメソッドをオーバーライドするときに呼び出すことが必須ではないと想定することは非常に安全です。デフォルトの動作を使用する(super
メソッドを呼び出す)か、完全にオーバーライドするかは、コンシューマ開発者が決定します。
条件が許可されている場合(私はオープンソースソフトウェアが大好きです)、コンシューマ開発者はいつでもAPIソースコードをチェックアウトし、メソッドが実際にどのように内部で記述されているかを確認できます。 Activity.onCreate()
source および DefaultHandler.startElement()
source などを確認してください。
頭の中で行うべきテストは次のとおりです。
「このメソッドのすべての機能を実行してから、後で何かを実行したいですか?」はいの場合、super()
を呼び出してから、メソッドを終了します。これは、バックグラウンドで多くのことを処理するonDraw()
などの「重要な」メソッドに当てはまります。
(オーバーライドするほとんどのメソッドのように)一部の機能のみが必要な場合は、おそらくsuper()
を呼び出したくないでしょう。
よくXaviはより良い答えを与えました..しかし、おそらくオーバーライドされたメソッドで呼び出されたときにsuper()
が何をするか知っているかもしれません... ..
例えば:
_onDraw()
_
ビュークラスのメソッドはオーバーライドされます。ビューが完全に描画されると、super.onDraw()と言う前に何かを描画します。したがって、ここではsuper
を呼び出す必要がありますAndroidいくつかの非常に重要なことがあります(onCreate()など)
しかし同時に
_onLongClick()
_
これをオーバーライドする場合、EditTextまたは他の同様のビューのオプションのリストを含むダイアログが表示されるため、superを呼び出したくありません。それが基本的な違いです。 onCreate() , onStop()
などの他のメソッドでは、OSに処理させる必要があります。
のような制約配列リストを実装しました
public class ConstraintArrayList<T> extends ArrayList<T> {
ConstraintArrayList(Constraint<T> cons) {this.cons = cons;}
@Override
public boolean add(T element) {
if (cons.accept(element))
return super.add(element);
return false;
}
}
コードを見ると、実際にスーパークラスにリストへの要素の実際の追加を実行させる前に、事前チェックを行うだけです。これは、メソッドをオーバーライドする2つの理由の1つを示しています。
私はあなたの質問をはっきりとは知りませんでしたが、super
メソッドを呼び出さない理由について質問している場合:
super
メソッドを呼び出す理由があります。親クラスに引数なしのコンストラクタがない場合、そのための子クラスを作成することはできないため、引数なしのコンストラクタを保持する必要があります親クラス、またはsuper()
呼び出しステートメントを子クラスコンストラクターの最上部にargument(how much argument constructor you have used in super class)
で定義する必要があります。
これがお役に立てば幸いです。そうでない場合は、お知らせください。