2017-11-29 16 views
2

다음 예제에서는 반환 유형 List<? extends IConfigUser>List<ConfigUser>으로 대체 할 수 있습니까? getUserList()에 있는데도 setUserList() 매개 변수에 대해 동일하게 처리 할 수 ​​없습니까?이 클래스가 매개 변수로 수퍼 유형으로 간주되지 않는 이유는 무엇입니까?

이 경우 IConfigUserConfigUser이 슈퍼 유형으로 간주되지 않습니까?

public class Test { 
    public interface IConfigUser { 
    } 

    public interface IConfig { 
     public List<? extends IConfigUser> getUserList(); 
     public void setUserList(List<? extends IConfigUser> list); 
    } 


    public class ConfigUser implements IConfigUser { 
    } 

    // The type Test.Config must implement the inherited abstract method 
    // Test.IConfig.setUserList(List<? extends Test.IConfigUser>) 
    public class Config implements IConfig { 
     @Override 
     public List<ConfigUser> getUserList() { 
     return null; 
     } 

     // The method setUserList(List<ConfigUser> list) of type Test.Config 
     // must override or implement a supertype method 
     @Override 
     public void setUserList(List<ConfigUser> list) 
     { 
     } 
    } 
} 
+0

* 컴파일 한 다음 List 에 누군가 전달한 경우를 상상해보십시오. –

답변

1
당신은 반환 할 수

당신이 IConfig 기준에 해당 메서드를 호출하는 경우 즉, 때문에 공분산에 당신이 알고있는 모든 당신이 얻을 것이 오 getUserList()의 반환 유형 ("전문")를 List<? extends IConfigUser>List<ConfigUser>List<? extends IConfigUser>입니다 그래서 요구 사항은 만족된다.

Config 참조로 전화하면 더 구체적이지만 기본 요구 사항은 여전히 ​​충족됩니다. setUserList(...)

는 상황이 다르다 : 당신이 다른List<ConfigUser>하지만 그것도 할 수있는 일이, 예를 들어, 할 수 있습니다 List<? extends IConfigUser> "서브 클래스"를 전달할 수 있습니다 a List<SomeConfigUser>.

의 구체적인 일반 매개 변수를 알 수 없으므로 setUserList(List<ConfigUser> list)에서 컴파일러는 해당 목록에서 읽기만 허용하고 위에 추가하지 마십시오. 위와 같은 이유에서 알 수 없습니다. 목록에 SomeConfigUser 인스턴스 만 추가 할 수 있기 때문에 얻은 ​​정보와 ConfigUser을 추가 할 수 있는지 여부가 허용됩니다.

+0

철저히 설명해 주셔서 감사합니다. – Zhro

2

당신은 IConfig에 제네릭 형식 매개 변수를 추가하여 목표를 달성 할 수

public class Test { 
    public interface IConfigUser { 
    } 

    public interface IConfig<T extends IConfigUser> { 
     public List<T> getUserList(); 
     public void setUserList(List<T> list); 
    } 


    public class ConfigUser implements IConfigUser { 
    } 

    public class Config implements IConfig<ConfigUser> { 
     @Override 
     public List<ConfigUser> getUserList() { 
     return null; 
     } 

     @Override 
     public void setUserList(List<ConfigUser> list) 
     { 
     } 
    } 
} 
2

을 당신은 반환 오버라이드 (override)에서 더 구체적인 유형, 그러나 당신이 필요로 할 수는 없습니다 당신 을 보다 구체적인 유형을 수락하십시오. 제네릭을 제거하고 String을 반환하는 메서드로 Object을 반환하는 메서드를 재정의 할 수 있지만 String 매개 변수를 수락하는 메서드를 사용하여 Object 매개 변수를 받아들이는 메서드를 재정의 할 수는 없습니다.

발신자가 호환 가능하도록 모든 것이 있습니다. 고려 :

IConfig config = new Config();  
List<SomeOtherConfigUser> list = new ArrayList<SomeOtherConfigUser>(); 
list.add(new SomeOtherConfigUser()); 
config.setUserList(list); 

아차 - Config.setUserListConfigUser 아닌 SomeOtherConfigUser 될 모든 요소를 ​​기대하고있다 당신.