117

独自のAndroidカスタムクラスを作成すると、extendそのネイティブクラスになります。次に、基本メソッドをオーバーライドする場合は、、などでいつも行うように、常にメソッドsuper()を呼び出します。onCreateonStop

superそして、Androidチームが最初からすべてのメソッドのオーバーライドを常に呼び出すようにアドバイスしていたので、これがそれだと思いました。

しかし、多くの本で、私より経験豊富な開発者が電話superを省略していることがよくあり、知識の欠如としてそれを行っているとは本当に思えません。たとえば、この基本的なSAXパーサークラスを見てください。ここでは、、および:superで省略されています。startElementcharactersendElement

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。この特定の例にバインドしないでください。これは、多くの例からランダムに選択された単なる例です。

(これは初心者の質問のように聞こえるかもしれませんが、私は本当に混乱しています。)

4

7 に答える 7

149

メソッドを呼び出すことで、メソッドの動作をオーバーライドsuperするのではなく、メソッドを拡張します。

toを呼び出すと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
    }
}

toを呼び出すと、との両方のロジックがこの特定の順序でB.save()実行されます。あなたが内部に電話をかけていなかったら、呼ばれなかったでしょう。そして、あなたが後に電話をかけた場合、後で効果的に実行されます。save()ABsuper.save()B.save()A.save()super.save()save(b)A.save()B.save()

の動作をオーバーライド したい場合super(つまり、その実装を完全に無視してすべて自分で提供したい場合)、を呼び出すべきではありませんsuper

SAXParser提供する例では、これらのメソッドの実装DefaultHandlerであるため、サブクラスはそれらをオーバーライドして、これらのメソッドの動作を提供できます。このメソッドのjavadocでは、これも指摘されています。

public void startElement (String uri, String localName,
    String qName, Attributes attributes) throws SAXException {
    // no op
}

彼のコメントで指摘されているように、super()IDEによって生成されたコードのデフォルトの呼び出しについては、各コンストラクターに暗黙の呼び出しがあります(コードに記述していなくても)。つまり、そのコンテキストでは、'への呼び出しを意味します。 ■デフォルトのコンストラクタ。ただそれを書き留めますが、それを削除すると呼び出されます。また、コンストラクター、または引数(つまり)を持つそのバリアントのいずれかを実装する場合は、メソッドの最初でのみ呼び出すことができることに注意してください。@barsjusuper()superIDEsuper()super(x,y,z)

于 2012-04-20T10:53:19.687 に答える
16

あなたがスーパーに電話しなければならないとき、そしてあなたがそれを呼び出すことを省略できるとき、彼らはどうやってそれを知るのですか?

Activity.onCreate()通常、特別なAPIメソッドが、基盤となるフレームワークコンテキストのライフサイクルにとって重要な意味を持つ場合、APIドキュメントのように、 APIドキュメントで常に明示的に記述され、強調表示されます。さらに、APIが堅牢な設計に従っている場合は、プロジェクトのコンパイル時にコンシューマー開発者に警告するためにいくつかの例外をスローし、実行時に障害が発生しないようにする必要があります。

これがAPIドキュメントに明示的に記載されていない場合、コンシューマー開発者は、APIメソッドをオーバーライドするときに呼び出す必要がないと想定するのが非常に安全です。superデフォルトの動作を使用する(メソッドを呼び出す)か、完全にオーバーライドするかを決定するのは、コンシューマー開発者の責任です。

条件が許可されている場合(私はオープンソースソフトウェアが大好きです)、コンシューマー開発者はいつでもAPIソースコードをチェックして、メソッドが実際に内部でどのように記述されているかを確認できます。たとえば、Activity.onCreate()ソースDefaultHandler.startElement()ソースを確認してください。

于 2012-04-20T11:53:06.217 に答える
8

あなたが頭の中で行うべきテストは次のとおりです。

「このメソッドのすべての機能を実行して、後で何かを実行したいですか?」はいの場合は、を呼び出しsuper()てからメソッドを終了します。onDraw()これは、バックグラウンドで多くのことを処理するなどの「重要な」メソッドに当てはまります。

一部の機能のみが必要な場合(オーバーライドするほとんどのメソッドと同様)、おそらくを呼び出したくないでしょうsuper()

于 2012-04-20T11:24:18.337 に答える
3

Xaviはより良い答えを出しました。しかし、オーバーライドされたメソッドで呼び出されたときに何が行われるかを知っているかもしれませんsuper()...デフォルトの動作で何をしたかをアドバタイズします。

例えば:

onDraw() 

オーバーライドされたときのビュークラスのメソッド..super.onDraw()と言う前に何かを描画すると、ビューが完全に描画されると表示されます。Androidにはsuper非常に重要なことがいくつかあるため、ここで呼び出す必要があります(onCreate()など)。

しかし同時に

onLongClick()

これをオーバーライドすると、EditTextまたは他の同様のビューのオプションのリストを含むダイアログが表示されるため、superを呼び出したくありません。これが基本的な差分です。あなたのような他の方法onCreate() , onStop()はOSにそれを処理させるべきです。

于 2012-04-20T11:01:27.850 に答える
3

私は次のような制約配列リストを実装しました

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つを示しています。

  1. スーパークラスができることを拡張したい拡張性
  2. 鳥の移動(フライ)とカエルの移動(ホップ)の方法が各サブクラスに固有である移動セマンティクスの一般的な動物界の例のように、ポリモーフィズムを通じて特定の動作を追加する場合の特異性。
于 2012-04-24T18:31:45.620 に答える
2

私はあなたの質問をはっきりと理解しませんでした、しかしあなたがなぜメソッドを呼び出さないのかについて尋ねているならsuper

メソッドを呼び出す理由がありsuperます。親クラスにゼロ引数コンストラクターがない場合、その子クラスを作成することはできないため、親クラスに引数なしコンストラクターを保持する必要があるか、次のいずれかが必要です。子クラスコンストラクターの先頭でsuper()呼び出しステートメントを定義します。argument(how much argument constructor you have used in super class)

これがお役に立てば幸いです。そうでない場合は、私に知らせてください。

于 2012-04-20T11:07:33.013 に答える
2

Android Frameworkのどのオーバーライドされたメソッドを呼び出すべきか疑問に思ってsuper、この質問を見つけた人のために-ここに2019年からの現在のヒントがあります-AndroidStudio3+はあなたがそれを必要とするときにあなたに教えてくれます

ここに画像の説明を入力してください

于 2019-03-15T10:38:42.733 に答える