私はthis questionに記載されている問題に直面していますが、キャストと@SuppressWarningアノテーションをすべて持たない解決策(可能な場合)を探したいと思います。継承メソッドが参照型を返しました
より良い解決策はによって参照される1つ上に構築されています1のようになります。ここで紹介する
ソリューションに基づいて2ポイントで採点されます
- 基準。 Bountyは2ポイント以上のものがあればほとんどのポイントまたは "最もエレガントな"ポイントに解決策をとる。
私はthis questionに記載されている問題に直面していますが、キャストと@SuppressWarningアノテーションをすべて持たない解決策(可能な場合)を探したいと思います。継承メソッドが参照型を返しました
より良い解決策はによって参照される1つ上に構築されています1のようになります。ここで紹介する
ソリューションに基づいて2ポイントで採点されます
ノーキャスト、無@SuppressWarning、数行のみ:
public abstract class SuperClass<T extends SuperClass<T>> {
protected T that;
public T chain() {
return that;
}
}
public class SubClass1 extends SuperClass<SubClass1> {
public SubClass1() {
that = this;
}
}
public class SubClass2 extends SuperClass<SubClass2> {
public SubClass2() {
that = this;
}
}
これは最高の答えとして選ばれました。これは、キャストを完全に避け、@SuppresWarningsを持たないし、私によれば、メソッドオーバーライドも避けているからです。必要なコードが少なくて済み、ユーザーが何も上書きしないように隠されています)。 23時間で報奨金を授与されます。 – pnt
@pntこれは基本的に、あなたの参照している質問の受け入れられた答えと同じ解決策です。なぜあなたはそれが好きで、ここでそれを受け入れなかったのですか? –
@FrancoisBourgeois実際、これは同じ解決策ではありません。他の解決策では、抽象クラスでは、コンパイル時にコンパイル時にキャストが安全かどうかを知ることができません(たとえ可能でも、開発者だけが知っています)。 @SuppressWarningアノテーション私のソリューションでは、 'that'がサブクラス内に直接設定されているので、キャストする必要はありません。そして、この*ノーキャストソリューション*は、正確にここで尋ねられたものです。 – sp00m
解決策の1つは、子クラスのメソッドをオーバーライドし、戻り値の型をより具体的なものに変更することです。子タイプです。これには鋳造が必要です。代わりに、典型的な(Child)
キャストを使用しての、キャストは、標準的な方法の中に隠されている
public class Parent {
public Parent example() {
System.out.println(this.getClass().getCanonicalName());
return this;
}
}
public class Child extends Parent {
public Child example() {
return Child.class.cast(super.example());
}
public Child method() {
return this;
}
}
をClass#cast(Object)
メソッドを使用します。ソースはClass
です。
public T cast(Object obj) {
if (obj != null && !isInstance(obj))
throw new ClassCastException(cannotCastMsg(obj));
return (T) obj;
}
キャストを取り除かずに(単にラップして隠す)、参照された質問の元の問題を解決しないため、解決策ではありません。はい、もちろん、より具体的な型を返すためにメソッドをオーバーライドすることができますが、全体のポイントはそれを再利用し、各子でオーバーライドする必要はありません。 – pnt
@pnt問題は_私は追加のインタフェースと余分なメソッドを使わずにこれを実装したいし、クラスキャスト、補助引数などを使わずにこれを使用したいと思っています。提案されたソリューションはすべて、余分な方法と追加の引数のいずれかを持っています。問題のメソッドをオーバーライドするか、親に別のメソッドを導入してオーバーライドします。 Genericsソリューションでは、型パラメータも導入する必要があります。 –
一つのアプローチは、Parent
クラスで抽象メソッドgetThis()
を定義し、すべてのChild
クラスはthis
参照を返す、それを上書きすることです。これは、クラス階層でthis
オブジェクトのタイプを回復する方法です。コードは次のようになり
:要件ごとに
abstract class Parent<T extends Parent<T>> {
protected abstract T getThis();
public T example() {
System.out.println(this.getClass().getCanonicalName());
return getThis();
}
}
class ChildA extends Parent<ChildA> {
@Override
protected ChildA getThis() {
return this;
}
public ChildA childAMethod() {
System.out.println(this.getClass().getCanonicalName());
return this;
}
}
class ChildB extends Parent<ChildB> {
@Override
protected ChildB getThis() {
return this;
}
public ChildB childBMethod() {
return this;
}
}
public class Main {
public static void main(String[] args) throws NoSuchMethodException {
ChildA childA = new ChildA();
ChildB childB = new ChildB();
childA.example().childAMethod().example();
childB.example().childBMethod().example();
}
}
、何鋳造なし@SuppressWarningsはありません。私はこのトリックを数日後にAngelika Langer - Java Generics FAQsから学びました。
参考:
'Parent
。ああ!右。ありがとう:) –
が原因のためのSO機構に2日に恵みを追加します贈り物を提供する。あなたの答えを今投稿してください。 – pnt
related:[型変数を持つ現在の型を参照する方法はありますか?](http://stackoverflow.com/questions/7354740/is-there-a-way-to-refer-to-the-current型付きの型) –