厳しいです:
私はシンプルな抽象的構造を持っています
public abstract class Data<A extends Serializable> {
}
このクラスの[文字列の実装
public class StringData extends Data<String> {
}
その後、私はインターフェイスを持っています:
public interface Testicek<A extends Serializable> {
public abstract Data<A> test(Data<A> bla);
}
そして今、私はこのインタフェースを実装するクラスを作成します:
public class TesticekImpl implements Testicek<String> {
// OK
@Override
public StringData test(Data<String> bla) {
return null;
}
// compilation error
//@Override
//public StringData test(StringData bla) {
// return null;
//}
}
なぜ私は、パラメータとして私StringDataクラスを使用することはできませんし、それが唯一の戻り値の型で動作しますか?戻り値の型とパラメータの署名は同じです。
アンディ・ターナー:
public interface Testicek<A extends Serializable> {
public abstract Data<A> test(Data<A> bla);
}
Javaが可能に共変戻り値の型、それらのより具体的な種類はまだ少ない固有の型のインスタンスであるため、インタフェースの実装は、親インタフェースよりも、より具体的な型を返すことができることを意味し、したがって、彼らはインターフェイスの契約を満たしています。
インターフェイスの契約は、それが受け入れなければならないことを言うのでしかし、あなたは、より具体的なパラメータ型を使用することはできません任意のその型のインスタンスを。
リスコフの置換原則は、サブクラスが無いより制限されているパラメータを受け入れなければならないことを教えてくれる、ノーより一般的である値を返す必要があります。
Javaは理由のため、あなたは「制限の少ない」パラメータの型を使用することはできません、それはコンパイル時に起動する方法を解決する方法(既にある、かなり複雑な)。これは、不必要に理論的な観点からの制限はなく、実用的な観点から、単純です。
あなたが受け入れ、同じ型を返すという点では:あなたのインタフェース内の別の型の変数を宣言します。
public interface Testicek<A extends Serializable, D extends Data<A>> {
public abstract D test(D bla);
}
次に、あなたの実装が可能。
public class TesticekImpl implements Testicek<String, StringData> {
@Override
public StringData test(StringData bla) {
return null;
}
}