V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
nealHuang
V2EX  ›  Java

Java 泛型接口方法实现疑惑,求各位大佬解答

  •  
  •   nealHuang · 2023-10-25 16:47:01 +08:00 · 1229 次点击
    这是一个创建于 381 天前的主题,其中的信息可能已经有所发展或是发生改变。

    接口 IHuman.java

    public interface IHuman<K, V> {
        V execute(K request) throws Exception;
    }
    

    实现 MaleHuman.java

    public class MaleHuman implements IHuman<String, String> {
        @Override
        public String execute(String request) throws Exception {
            return ...;
        }
    }
    

    按照以上接口内的泛型方法,能进行子类实现也不会报错。但是接口内的泛型方法换种写法,就不知道如何写实现了。

    接口 IHuman.java (改)

    public interface IHuman {
        <K, V> V execute(K request) throws Exception;
    }
    

    请问按上述接口内的泛型方法,如何类似泛型类的实现那样,写 MaleHuman.java 这个实现类。

    8 条回复    2023-10-26 10:01:45 +08:00
    gaifanking
        1
    gaifanking  
       2023-10-25 16:58:15 +08:00   ❤️ 1
    idea 自动生成代码如下:
    @Override
    public <K, V> V execute(K request) throws Exception {
    return null;
    }

    这种是方法泛型,仅该方法可用,没看懂你的目的是啥。
    AoEiuV020JP
        2
    AoEiuV020JP  
       2023-10-25 17:08:17 +08:00
    后一个 IHuman 这种写法是限制运行时 K 和 V 具体类型的,
    而前面代码可以保证 MaleHuman 中的 K 和 V 都是 String ,这是本质区别,无法翻译代码的,
    AoEiuV020JP
        3
    AoEiuV020JP  
       2023-10-25 17:10:11 +08:00
    @AoEiuV020JP #2 后一个 IHuman 这种写法是不能限制运行时 K 和 V 具体类型的,
    xianyv
        4
    xianyv  
       2023-10-25 17:11:07 +08:00
    可以这样

    ```java
    interface HumanExtend extends IHuman {

    @Override
    <K extends String, V extends String> V execute(K request) throws Exception;
    }

    class HumanImpl implements HumanExtend{
    @Override
    public <K extends String, V extends String> V execute(K request) throws Exception {
    return null;
    }
    }
    class HumanImplTwo implements HumanExtend{

    @Override
    public String execute(String request) throws Exception {
    return null;
    }
    }

    ```
    levintrueno
        5
    levintrueno  
       2023-10-25 17:20:47 +08:00
    第一个是泛型接口 + 普通方法。第二个是普通接口 + 泛型方法。应该去了解泛型类和泛型方法的区别。
    nealHuang
        6
    nealHuang  
    OP
       2023-10-25 17:36:29 +08:00
    @gaifanking 是为了在 MaleHuman 中把两个泛型都限制为 String ,如果也都是泛型,那就胡乱传了
    yidinghe
        7
    yidinghe  
       2023-10-25 23:10:33 +08:00
    <K, V> 这样的泛型参数,如果是在 class 级别定义,就表示这两个类型在整个类中有效,每个方法都可以定义这两个类型的变量或参数。

    如果 <K, V> 是在某个方法上定义,就像你 IHuman.java (改) 的例子,那么这两个类型就只能在这个方法内使用,这个类的其他方法则无法使用。

    ```java
    // 实现类
    public class HumanImpl implements IHuman {

    @Override
    public <K, V> V execute(K request) throws Exception {
    // 这个方法里面可以使用 K ,V 类型的变量
    return (V) request;
    }

    // 使用例子
    public static void main(String[] args) {
    var result = new HumanImpl().<String, String>execute("haha"); // 返回 "haha"
    }
    }
    ```
    gaifanking
        8
    gaifanking  
       2023-10-26 10:01:45 +08:00
    @nealHuang 那就是 4 楼老哥 @xianyv 的办法:
    方法泛型中使用 extends 关键字:<K extends String, V extends String> V execute(K request), 限定 K V 类型
    extends super 关键字也可以加在类泛型上,注意 PECS 原则。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   1040 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 31ms · UTC 23:09 · PVG 07:09 · LAX 15:09 · JFK 18:09
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.