4

私の一部は、これは可能であってはならないと考えていますが (可能であっても)、とにかく質問します。

次のクラス階層が与えられた場合 (GrandparentおよびParentサード パーティからのものであるため、私の管理下にはありません)、オーバーライドされた実装をバイパスして の実装を呼び出すようにオーバーライドmyMethod()するにはどうすればよいでしょうか?ChildParentGrandparent

class Grandparent {
   public void myMethod() {
      // do stuff
   }
}

class Parent extends Grandparent {
   @Override public void myMethod() {
      super.myMethod();
      // do something else
   }
}

class Child extends Parent {
   @Override public void myMethod() {
      // ??? I want to *only* do what Grandparent did here
   }
}

Parentクラスが他の多くの役立つ動作を提供し、 の階層の重要な要素であるふりをします (つまり、「のサブクラスをChild作成する」ことを探しているわけではありません。ChildGrandparent

4

4 に答える 4

10

継承の背後にある考え方は、各クラスが必要な方法でメソッドを定義するため、コードを検査する必要がないということです。

ここでは、コードを再利用するためだけにサブクラス化しているようですが、それはサブクラス化の考え方ではありません。

たぶん、サブクラス化する代わりに、必要なタスクのいくつかを実行するヘルパーメンバーが必要であり、「子」クラスと「親」クラスの両方に「祖父母」を拡張させる必要があります。

あなたが自分自身に尋ねる必要がある主な質問は、「子供は本当に親、祖父母、またはネイターの子孫ですか?」です。言い換えれば、子のすべてのインスタンスについて、それが親であると言えますか?

答えが「いいえ」の場合、誤ってサブクラス化しています。継承は、コードの再利用だけでなく、何かを意味することになっています(つまり、「フォード「車」メソッドを使用するだけでなく、フォードも車です)。

于 2009-04-07T17:07:10.573 に答える
3

親または祖父母のコードに触れることができなかったと仮定し、そうではないと仮定すると、Sebが示唆したように(そしてSteveが明らかに同意したように)、継承を完全に誤用しただけです:

Grandfather オブジェクト (抽象オブジェクトの場合は Grandfather を拡張するローカル クラス) のローカル インスタンスを作成し、myMethod() の解釈に直接アクセスします。もちろん、myMethod() が読み取るおよび/または操作する状態情報の量に応じて、関連する作業の量は「簡単」から「耐え難い」ものになる可能性があります。

これは醜い解決策であり、状態情報にアクセスする量によっては、非常に脆弱になる可能性があります。しかし、Grandfather が確実に安定しており、myMethod() がかなり自己完結型である場合、動作する可能性があります。いつものように、悪魔は細部に宿ります。

これは継承ではなく再利用であるという点で、私は間違いなくセブに同意します。でもね。多くの場合、再利用は良いことです。

于 2009-04-07T17:53:50.570 に答える
2

親クラスを管理できますか?

もしそうなら、祖父母でmyMethodを呼び出すメソッド(myNewMethod)を親に追加し、子からmyNewMethodを呼び出すことができますか?

(私はJavaの人間ではないので、サブクラスのメソッドのオーバーライドからのみスーパークラスのメソッドを呼び出すことができるかどうかはわかりません)

class Grandparent {
   public void myMethod() {
      myHelperMethod();
   }
}

class Parent extends Grandparent {
   @Override public void myMethod() {
      super.myMethod();
      // do something else
   }
   public final void myNewMethod() {
      super.myMethod();
   }
}

class Child extends Parent {
   @Override public void myMethod() {
      // ??? I want to *only* do what Grandparent did here
      myNewMethod();
   }
}
于 2009-04-07T16:58:09.987 に答える
2

ありえない。

final代わりに、祖父母にヘルパー メソッドを作成します。そして、このメソッド (オーバーライドされます) がそのヘルパーを呼び出すようにします。

class Grandparent {
   public final void myHelperMethod() {
      // do stuff
   }
   public void myMethod() {
      myHelperMethod();
   }
}

class Parent extends Grandparent {
   @Override public void myMethod() {
      super.myMethod();
      // do something else
   }
}

class Child extends Parent {
   @Override public void myMethod() {
      // ??? I want to *only* do what Grandparent did here
      myHelperMethod();
   }
}
于 2009-04-07T16:44:39.677 に答える