class A {
public A get() { }
}
class B extends A {
}
戻り型は継承されたメソッドと互換性がありません。この問題を解決するにはどうすればよいですか?
class A {
public A get() { }
}
class B extends A {
}
戻り型は継承されたメソッドと互換性がありません。この問題を解決するにはどうすればよいですか?
JDK 5 以降、Java では、新しい型が元の型のサブクラスである限り、オーバーライドされたメソッドの戻り値の型を変更できます。これは共変の戻り型と呼ばれます。次のコードは正しくコンパイルされます。
class A {
A get() {
return new A();
}
void sayHello(){
System.out.println("Hello");
}
}
class B extends A {
@Override
B get() {
return new B();
}
void sayGoodbye(){
System.out.println("Goodbye");
}
}
class Test{
void check(){
B two=new B();
two.get().sayGoodbye();
}
}
オーバーライドされたメソッドの戻り値の型は、戻り値の型のサブクラスである必要があることに注意してください。これにより、A 変数でメソッドを呼び出して、有効な A オブジェクト (実際には B インスタンス) を取得できるようになります。
void check(){
A two=new B();
A copy=two.get();
copy.sayHello();
}
B b = new B().get();
Nikita Beloglazov が提案するような明示的な型キャストなしのようなものを書きたいと思っていると思いますが、それは Java が十分にサポートしているイディオムではありません。ユージーンの答えは十分に機能しますが、それにはまだキャストが含まれてT
おり、さらに醜いコンパイラ警告が生成されます。個人的には、次のようなコードを書きます。
class A {
private A() {}
public A get() {
return new A();
}
}
class B extends A {
private B() {}
@Override
public A get() {
return new B();
}
public B getB() {
return (B) get();
}
}
を行うことはできませんがB b = new B().get();
、行うことはできます。これは、オブジェクトだけでなくB b = new B().getB();
、オブジェクトが必要であることを既に知っているため、とにかく簡単で、とにかくもう少し自己文書化できます。そして、 で宣言されたメソッドにしかアクセスできない B オブジェクトを作成します。B
A
A a = new B().get();
A
ジェネリックを使用する:
class A<T extends A> {
public T get() { }
}
class B extends A<B> {
}
B b = new B();
B got = b.get();