답변:
공변 반환은 메서드를 재정의 할 때 재정의 된 메서드의 반환 유형이 재정의 된 메서드의 반환 유형의 하위 유형이 될 수 있음을 의미합니다.
예제를 통해이를 명확히하기 위해 일반적인 경우는 Object.clone()
-형식을 반환하도록 선언됩니다 Object
. 다음과 같이 자신의 클래스에서이를 재정의 할 수 있습니다.
public class MyFoo
{
...
// Note covariant return here, method does not just return Object
public MyFoo clone()
{
// Implementation
}
}
여기서 이점은 MyFoo 객체에 대한 명시 적 참조를 보유하는 모든 메서드가 clone()
반환 값이의 인스턴스임을 (캐스팅하지 않고) 호출 하고 알 수 있다는 것 입니다 MyFoo
. 공변 반환 유형이 없으면 MyFoo의 재정의 된 메서드가 반환되도록 선언해야합니다. Object
따라서 호출 코드는 메서드 호출의 결과를 명시 적으로 다운 캐스트해야합니다 (양측이 "알고"있다고 생각하더라도 항상 MyFoo의 인스턴스 일 수 있다고 생각). ).
특별한 것은 없으며 clone()
재정의 된 메서드는 공변 반환을 가질 수 있습니다. 여기서는 이것이 종종 유용한 표준 메서드이기 때문에 예제로 사용했습니다.
List<Foo>
및List<FooBar>
?
clone()
으로 생각 Method<Void, Object>
하고 더 구체적인 항목 Method<Void, MyFoo>
을 해당 상위 유형에 할당 할 수 있는지 물어볼 수 있습니다. Java 메소드가 반환 유형에서 공변하는 경우에만 그렇습니다.
다음은 또 다른 간단한 예입니다.
Animal
수업
public class Animal {
protected Food seekFood() {
return new Food();
}
}
Dog
수업
public class Dog extends Animal {
@Override
protected Food seekFood() {
return new DogFood();
}
}
아래와 같이 Dog
의 seekFood()
메서드 의 반환 유형 을 DogFood
-의 하위 클래스 로 수정할 수 Food
있습니다.
@Override
protected DogFood seekFood() {
return new DogFood();
}
그것은 완벽하게 합법적 인 재정의이며 Dog
의 seekFood()
메서드 의 반환 유형은 공변 반환 유형으로 알려져 있습니다.
JDK 1.5 릴리스부터 공변 유형이 Java에 도입되었습니다. 간단한 사례로 설명 하겠습니다. 함수를 재정의하면 함수가 동작을 변경할 수 있습니다. 대부분의 책에서 읽을 수있는 을 변경할 수 있지만 {저자}가 놓친 부분은 반환 유형도 변경할 수 있다는 것입니다. 아래 링크를 확인하여 메서드의 기본 버전 반환 유형에 할당 할 수있는 한 반환 유형을 변경할 수 있습니다.
따라서 파생 된 형식을 반환하는이 기능을 COVARIANT라고합니다.
공변 반환 유형은 단순히 자신의 클래스 참조 또는 하위 클래스 참조를 반환하는 것을 의미합니다.
class Parent {
//it contain data member and data method
}
class Child extends Parent {
//it contain data member and data method
//covariant return
public Parent methodName() {
return new Parent();
or
return Child();
}
}
Parent.foo()
다시 표시 무관 유형 A
및 Child.foo()
반환 일종 B
으로부터 유도를 A
.
공변 반환 유형은 반환 유형이 하위 클래스와 동일한 방향으로 다를 수 있음을 지정합니다.
class One{
One get(){return this;}
}
class Two extends One{
Two get(){return this;}
void message(){
System.out.println("After Java5 welcome to covariant return type");
}
public static void main(String args[]){
new Two().get().message();
}
}
Java 5 이전에는 반환 유형을 변경하여 메서드를 재정의 할 수 없었습니다. 하지만 지금은 Java5 이후로
서브 클래스가 리턴 유형이 Non-Primitive 인 메소드를 대체하지만 리턴 유형을 서브 클래스 유형으로 변경하는 경우 리턴 유형을 변경하여 메소드를 대체 할 수 있습니다.
- Java의 공변 반환 유형을 사용하면 재정의 된 메서드의 반환 유형을 좁힐 수 있습니다.
- 이 기능은 클라이언트 측에서 다운 캐스팅을 방지하는 데 도움이됩니다. 프로그래머가 유형 검사 및 다운 캐스팅없이 프로그래밍 할 수 있습니다.
- 공변 반환 유형은 항상 기본이 아닌 반환 유형에 대해서만 작동합니다.
interface Interviewer {
default Object submitInterviewStatus() {
System.out.println("Interviewer:Accept");
return "Interviewer:Accept";
}
}
class Manager implements Interviewer {
@Override
public String submitInterviewStatus() {
System.out.println("Manager:Accept");
return "Manager:Accept";
}
}
class Project {
public static void main(String args[]) {
Interviewer interviewer = new Manager();
interviewer.submitInterviewStatus();
Manager mgr = new Manager();
mgr.submitInterviewStatus();
}
}
다른 예는 Java입니다.
UnaryOperator.java
@FunctionalInterface
public interface UnaryOperator<T> extends Function<T, T> {
/**
* Returns a unary operator that always returns its input argument.
*
* @param <T> the type of the input and output of the operator
* @return a unary operator that always returns its input argument
*/
static <T> UnaryOperator<T> identity() {
return t -> t;
}
}
Function.java
@FunctionalInterface
public interface Function<T, R> {
........
........
........
........
static <T> Function<T, T> identity() {
return t -> t;
}
}
Java5 이전에는 반환 유형을 변경하여 메서드를 재정의 할 수 없었습니다. 그러나 이제 Java5부터는 서브 클래스가 리턴 유형이 Non-Primitive 인 메소드를 대체하지만 리턴 유형을 서브 클래스 유형으로 변경하면 리턴 유형을 변경하여 메소드를 대체 할 수 있습니다.