심한 :
나는 간단한 추상 구조
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);
}
자바는 수 공변 반환 형식 들보다 특정 유형이 아직 덜 특정 유형의 인스턴스이기 때문에, 인터페이스의 구현이 상위 인터페이스보다 더 많은 특정 유형을 반환 할 수있는 수단을, 따라서 그들은 인터페이스의 계약을 만난다.
인터페이스의 계약이 동의해야 함을 말한다 때문에, 당신은보다 구체적인 매개 변수 유형을 사용할 수 있는 해당 유형의 인스턴스를.
리스 코프 치환 원칙은 서브 클래스가 더 이상 제한적인 매개 변수를 허용해야하고, 더 일반적입니다 값을 반환해야한다는 것을 우리에게 알려줍니다.
자바의 때문에, "덜 제한적인"매개 변수 유형을 사용하는 것을 허용하지 않는 방법은 컴파일 타임에 호출하는 방법을 해결합니다 (이미 꽤 복잡). 이 불필요하게 이론적 인 관점에서 제한하지만, 실용적인 관점에서 간단합니다.
당신이 받아들이고 동일한 유형을 반환 측면에서 : 당신의 인터페이스에서 다른 종류의 변수를 선언 :
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;
}
}