처음에 질문에서 언급 한 개념을 공변량 반환 유형 이라고 합니다 .
공변 리턴 유형은 메소드가 특정 유형의 오브젝트를 리턴해야하고 대체 메소드를 대체하면 실제로 서브 클래스를 리턴 할 수 있기 때문에 작동합니다. 경우, 자바와 같은 언어의 하위 유형 규칙에 따라 S
의 하위 유형이다 T
어디든지 다음, T
우리가 전달할 수 있습니다 나타납니다 S
.
따라서 S
예상되는 메서드를 재정 의 할 때 a 를 반환하는 것이 안전 합니다 T
.
재정의 된 메서드가 재정의 된 메서드에서 요청한 인수의 하위 유형 인 인수를 사용한다는 점을 받아들이 겠다는 제안은 형식 시스템에서 소리가 나지 않기 때문에 훨씬 더 복잡합니다.
한편으로, 위에서 언급 한 것과 동일한 하위 유형 규칙에 따라 대부분의 경우 이미 원하는 작업에 적용됩니다. 예를 들어
interface Hunter {
public void hunt(Animal animal);
}
이 클래스의 구현이 어떤 종류의 동물도받지 못하게 막는 것은 없습니다. 이미 질문의 기준을 충족하고 있기 때문입니다.
그러나 제안한대로이 방법을 무시할 수 있다고 가정 해 봅시다.
class MammutHunter implements Hunter {
@Override
public void hunt(Mammut animal) {
}
}
다음은 재미있는 부분입니다. 이제 할 수 있습니다.
AnimalHunter hunter = new MammutHunter();
hunter.hunt(new Bear()); //Uh oh
공용 인터페이스에 따라 AnimalHunter
모든 동물을 사냥 할 수 있어야하지만 구현에 따라 개체 MammutHunter
만 허용해야 Mammut
합니다. 따라서 재정의 된 메서드는 공용 인터페이스를 만족하지 않습니다. 우리는 방금 유형 시스템의 건전성을 깨뜨 렸습니다.
제네릭을 사용하여 원하는 것을 구현할 수 있습니다.
interface AnimalHunter<T extends Animal> {
void hunt(T animal);
}
그런 다음 MammutHunter를 정의 할 수 있습니다.
class MammutHunter implements AnimalHunter<Mammut> {
void hunt(Mammut m){
}
}
그리고 일반 공분산과 반공 분산을 사용하면 필요할 때 유리하게 규칙을 완화 할 수 있습니다. 예를 들어 포유류 사냥꾼이 특정 상황에서만 고양이를 사냥 할 수 있도록 할 수 있습니다.
AnimalHunter<? super Feline> hunter = new MammalHunter();
hunter.hunt(new Lion());
hunter.hunt(new Puma());
MammalHunter
구현을 가정 합니다 AnimalHunter<Mammal>
.
이 경우에는 허용되지 않습니다.
hunter.hunt(new Mammut()):
mammuts가 포유류 인 경우에도 여기서 사용하는 반 변형 유형에 대한 제한으로 인해 허용되지 않습니다. 그래서, 당신은 여전히 당신이 언급 한 것과 같은 것들을하기 위해 타입을 제어 할 수 있습니다.