2012-04-13 3 views
6

다음 코드는 Java에서 메서드 재정의 개념을 사용합니다.Java의 공변 반환 형식

package pkg; 

import java.util.ArrayList; 
import java.util.List; 

abstract class SuperClass 
{ 
    abstract public List<String>getList(); 
} 

final class SubClass extends SuperClass 
{ 
    private List<String>list=null; 

    @Override 
    public ArrayList<String> getList() 
    { 
     list=new ArrayList<String>(); 
     list.add("A"); 
     list.add("B"); 
     return (ArrayList<String>) list; 
    } 
} 

final public class Main 
{ 
    public static void main(String[] args) 
    { 
     SuperClass s=new SubClass(); 
     List<String>list=s.getList(); 

     for(String str:list) 
     { 
      System.out.println(str); 
     } 
    } 
} 

일반적으로 메소드 오버라이드는 수퍼 클래스와 서브 클래스 모두에서 동일한 서명 (리턴 유형 포함)을 사용합니다. 위의 코드에서 SuperClass에있는 getList() 메서드의 반환 유형은 List이고 해당 하위 클래스에서는 반환 유형이 ArrayList입니다. 메소드 재정의는 어떻게 작동합니까? 그런데

, 그것은 ArrayListList 인터페이스의 구현입니다 분명하지만 getList() 메서드를 재정의하면서 어떻게 컴파일러는 여기 반환 형식을 처리합니까?

이런 식으로 생각해야합니까 ... 재정의 된 메서드의 반환 형식은 재정의 된 메서드의 반환 형식의 하위 형식이 될 수 있습니다.

+0

'SubClass.list'를 선언 할 이유가'List' (가 아닌'ArrayList')로이 보인다. –

+0

@ MichaelBrewer-Davis -'SuperClass'처럼 취급하는 대신'SubClass'를 직접 사용하면 더 좋게 만들 수 있습니다. –

+0

@Brendan - 저는 (개인) 멤버 변수가 너무 일반적이어서 메서드가 너무 구체적이지는 않습니다. 방법의 공분산은 햇빛과 나비입니다. –

답변

19

예.

초기 자바에서는 그렇지 않았지만 Java 5.0에서 변경되었습니다.

반환 유형별로 다른 서명이있는 같은 클래스에는 두 개의 메소드를 사용할 수 없습니다. J2SE 5.0 릴리스까지는 클래스가 수퍼 클래스에서 상속 한 메서드의 반환 형식을 재정의 할 수 없다는 것도 사실이었습니다. 이 팁에서는 공변 리턴 유형을 허용하는 J2SE 5.0의 새로운 기능에 대해 학습합니다. 이것이 의미하는 것은 서브 클래스의 한 메소드가 슈퍼 클래스에서 같은 서명을 가진 메소드에 의해 리턴 된 타입의 서브 클래스 인 객체를 리턴 할 수 있다는 것입니다. 이 기능을 사용하면 과도한 유형 확인 및 캐스팅이 필요하지 않습니다.

이 정보의 출처는 더 이상 interwebs에서 사용할 수 없습니다.

+0

링크가 작동하지 않습니다. – Ghos3t

3

네, 맞습니다. ArrayList는 List이므로 원래 메서드가 List를 반환하면 ArrayList를 반환 할 수 있습니다.

4

개체 지향 프로그래밍에서 메서드의 공변 반환 형식은 메서드가 하위 클래스에서 재정의 될 때 "더 좁은"형식으로 대체 될 수있는 형식입니다. 이것이 매우 일반적인 패러다임 인 유명한 언어는 C++입니다. 공변 반환 형식은 (부분적으로) JDK5.0의 릴리스 이후 자바 언어에서 허용 된, 그래서 다음 예는 이전 버전에 컴파일되지 것입니다 : 좁은에 폭 (구체적

// Classes used as return types: 

class A { 
} 

class B extends A { 
} 

// "Class B is more narrow than class A" 
// Classes demonstrating method overriding: 

class C { 
    A getFoo() { 
     return new A(); 
    } 
} 

class D extends C { 
    B getFoo() { 
     return new B(); 
    } 
} 

공변를) 또는 반 변형 (좁은에서 넓은) 반환 유형은 대체 메서드의 반환 형식이 원래 재정의 메서드의 반환 형식과 관련된 형식 (그러나 다른 형식)으로 변경되는 상황을 나타냅니다.

두 공변량 반환 유형 간의 관계는 일반적으로 Liskov 대체 원칙에 따라 한 유형을 다른 유형으로 대체 할 수있는 유형입니다.

일반적으로 재정의 메서드의 반환 형식은 재정의 된 메서드의 반환 형식의 하위 형식이됩니다. 위의 예는 이러한 경우를 구체적으로 보여줍니다. 대입이 허용되지 않으면 반환 유형은 불변이며 컴파일 오류가 발생합니다.

참조 : https://en.wikipedia.org/wiki/Covariant_return_type

+0

https://en.wikipedia.org/wiki/Covariant_return_type –