私はそのように定義されたいくつかの継承クラスを持っています。Javaの多態性とメソッド連鎖
class Base {
public Base chainedMethodA() {
// some stuff
return this;
}
}
class Derived extends Base {
public Derived chainedMethodB() {
// some stuff
return this;
}
}
さて、次のコードは動作します:
Derived obj = new Derived();
obj.chainedMethodB().chainedMethodA();
しかし、これは(関数呼び出しの切り替え順に気づか)しません:
Derived obj = new Derived();
obj.chainedMethodA().chainedMethodB();
コンパイラがchainedMethodB()
にエラーが発生します関数呼び出し。これは、chainedMethodA()
を実行するとBase
のオブジェクトが返され、chainedMethodB
が定義されていないためです。
私は、この問題に対するいくつかの解決策を考えることができます(「最初の方法、およびそれからBase
呼び出す」Derived
を呼び出すの方法)を順番に注意を払いながら
- チェーン方法。これは非常に脆弱な解決策のように見えます。
chainedMethodA
をDerived
に上書きするため、Base
の代わりにDerived
のインスタンスを返します。これは相続の浪費のようです。
この問題を回避する方法はありますか?おそらくDerived
で明示的にオーバーライドされずにDerived
のオブジェクトによって呼び出されたときに、chainedMethodA
をDerived
インスタンスを返すように魔法のように変更するいくつかのコンストラクトです。 Derived
で
2は、継承の無駄ではありません。これは継承です:より具体的な何かを行うためのオーバーライドです。この場合、より具体的な型を返します。 – Tunaki
@TI確かにそうです:より具体的な型を返すようにオーバーライドして宣言することができます。 @Override public Derived chainedMethodA(){...} ' – Tunaki
' Derived'の 'chainedMethodA'が' Derived'のインスタンスを返すようにしたい場合は、とにかくsuper実装を呼び出すことはできませんそれは 'Derived 'ではない実際の' Base'を返すかもしれないからです)。そうして何かを失うことはありません。また、 'Derived'オブジェクトを' Base'として使うことができます。 –