首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >为什么这个类不被视为一个参数的超级类型?

为什么这个类不被视为一个参数的超级类型?
EN

Stack Overflow用户
提问于 2017-11-29 11:05:01
回答 3查看 237关注 0票数 2

在下面的示例中,为什么我能够将返回类型List<? extends IConfigUser>作为List<ConfigUser>覆盖到getUserList()中,但不能对setUserList()的参数执行相同的操作?

在这种情况下,ConfigUser不被认为是IConfigUser的超级类型吗?

代码语言:javascript
运行
复制
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)
      {
      }
   }
}
EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2017-11-29 11:11:26

您可以返回(“专门化”)由于协方差而返回的getUserList()类型,也就是说,如果您在IConfig引用上调用该方法,您所知道的就是您将得到一个List<? extends IConfigUser>,而List<ConfigUser>是一个List<? extends IConfigUser>,这样就满足了需求。

如果在Config引用上调用它,则信息更具体,但基本要求仍然满足。

使用setUserList(...),情况就不同了:它允许您传递List<? extends IConfigUser>的任何“子类”,这些子类可以是List<ConfigUser>,但也可以是其他的东西,例如List<SomeConfigUser>

顺便说一句,由于您不知道listsetUserList(List<ConfigUser> list)中的具体泛型参数,编译器也只允许您从该列表中读取,永远不要添加--原因与上面相同:您不知道您得到了什么,以及是否允许添加ConfigUser,因为列表只能允许添加SomeConfigUser实例。

票数 1
EN

Stack Overflow用户

发布于 2017-11-29 11:09:32

可以通过向IConfig添加泛型类型参数来实现目标。

代码语言:javascript
运行
复制
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
EN

Stack Overflow用户

发布于 2017-11-29 11:09:57

可以在覆盖中返回更特定的类型,但不能要求接受更特定的类型。去掉泛型,可以用返回Object的方法重写返回String的方法,但不能用接受String参数的方法覆盖接受Object参数的方法。

所有这些都是为了使呼叫者兼容。考虑:

代码语言:javascript
运行
复制
IConfig config = new Config();    
List<SomeOtherConfigUser> list = new ArrayList<SomeOtherConfigUser>();
list.add(new SomeOtherConfigUser());
config.setUserList(list);

哎呀--你的Config.setUserList期望每个元素都是一个ConfigUser,而不是一个SomeOtherConfigUser

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/47551294

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档