【问题标题】:Generics and inheritance - only supertypes needed in code泛型和继承——代码中只需要超类型
【发布时间】:2013-02-24 11:09:51
【问题描述】:

我需要在客户端代码中使用泛型类及其类型参数。

public class Usable {
    ...
}


public interface User<T extends Usable> {
    public void use(T usable);
}


//client
public class UserDemo { 
    public void demo() {
        Usable usable = getUsable();    //returns Usable
        User<? extends Usable> user = getUser();    //returns User<? extends Usable>

        user.use(usable); //compilation error.
    }

    public Usable getUsable() {
        ....
    }

    public User<? extends Usable> getUser() {
        ....
    }
}

编译错误是期望的类型是&lt;? extends Usable&gt;,但传递的类型是Usable。我该如何解决这个问题?约束是:

  1. 客户端代码(UserDemo) 只能在UserUsable(不是它们的子类型)上工作。
  2. 用户只能处理类型为Usable 子类型的对象。

【问题讨论】:

  • getUsable的签名是什么?你也用了两次,所以我想有一个错字。同时提供其他方法的签名。
  • 这段代码有不少错别字。请清理干净。
  • 用 getUser() 和 getUsable() 的定义更新了代码并更正了拼写错误。

标签: java generics inheritance interface


【解决方案1】:

这不行:

  • user.use(usable); 期望 User&lt;T extends Usable&gt; 的 T,它可以是 UsableUsable 的子类
  • usableUsable
  • getUser() 返回 ? extends Usable

所以你可以想象一个场景:

  • getUser 返回 SubUsableUsable 的子类
  • 意思是user.use() 需要SubUsable 并且不能接受你试图通过的Usable

如果您将getUser 的签名更改为返回Usable,它将起作用:

public void demo() {
    Usable usable = getUsable();
    User<Usable> user = getUser();
    user.use(usable);
}

public Usable getUsable() { return null; }

public User<Usable> getUser() { return null; }

【讨论】:

  • 是的,但是 getUser() 方法必须有一个返回类型,它是 User。
  • @pflz 在这种情况下,它可以返回一个user,它是一个User&lt;SubUsable&gt;,你不能将你的Usable usable 传递给User&lt;SubUsable&gt;...
  • 但我的客户端代码应该与 SubUsable 无关。它只知道类型参数是Usable的子类型。
  • 我想问题是我只需要使用类型参数可以是任何可用子类型的用户。
  • @pflz 我的意思是你的Usable usable 只能被User&lt;Usable&gt; 使用。因此,您的设计中的某些内容必须放松。另一种方法是将 getUser 的签名更改为:public &lt;T extends Usable&gt; User&lt;T&gt; getUser() 并保留User&lt;Usable&gt; user = getUser();
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-09-27
  • 2015-09-15
  • 2020-03-02
  • 1970-01-01
  • 2021-10-11
相关资源
最近更新 更多