나는 매개 변수로 클래스의 구현을 사용하여 메소드를 오버라이드 (override) 할 수없는 이유

심한 :

나는 간단한 추상 구조

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;
    }
}

추천

출처http://43.154.161.224:23101/article/api/json?id=185991&siteId=1