Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/389.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 奇怪的接口实现_Java_Interface - Fatal编程技术网

Java 奇怪的接口实现

Java 奇怪的接口实现,java,interface,Java,Interface,对不起,我之前的代码错了 所以我有一个界面,看起来像: public interface Player { void setPartner(Player partner); } 我有一个接口的实现,看起来像这样: public class Human implements Player { private Human partner; public void setPartner(Human partner) { this.partner

对不起,我之前的代码错了

所以我有一个界面,看起来像:

public interface Player { 
    void setPartner(Player partner); 
}
我有一个接口的实现,看起来像这样:

public class Human implements Player
{
    private Human partner;

    public void setPartner(Human partner)
    {
        this.partner = partner;
    }
}

因此,编译器说,我并不是从Player实现每个方法,这向我表明,我必须精确匹配setPartner方法的参数类型,即使人类是Player。有什么好方法可以绕过这个问题或以不同的方式实现它吗?

你不能有协变参数(如果你通过玩家界面操纵你的人类实例会发生什么情况?),但是你可以使用泛型

public interface Player<T extends Player<T>> {
    void setPartner(T partner);
}

public class Human implements Player<Human> {
    private Human partner;

    public void setPartner(Human partner) {
        this.partner = partner;
    }
}
公共界面播放器{
无效合伙人(T合伙人);
}
公共类人类工具播放器{
私人人类伙伴;
公共伙伴(人工伙伴){
这个。合伙人=合伙人;
}
}


但是,您不能强制实现类实际使用自己的类型作为播放器的类型参数。

您不能有协变参数(如果您通过播放器接口操纵您的人类实例会发生什么情况?),但是您可以使用泛型

public interface Player<T extends Player<T>> {
    void setPartner(T partner);
}

public class Human implements Player<Human> {
    private Human partner;

    public void setPartner(Human partner) {
        this.partner = partner;
    }
}
公共界面播放器{
无效合伙人(T合伙人);
}
公共类人类工具播放器{
私人人类伙伴;
公共伙伴(人工伙伴){
这个。合伙人=合伙人;
}
}


但是,您不能强制实现类实际使用自己的类型作为播放器的类型参数。

在Java中,方法参数是不变的。这意味着
void-setPartner(Player-partner)
方法签名不同于
void-setPartner(Human-partner)
方法签名,即使
Human
是一个
Player
。因此,您不能像这样实现(或覆盖)


扩展类时必须小心,因为如果
Player
是一个类,并且方法不是抽象的,而不是实际工作的方法,但是您会重载方法而不是重写它。

在Java中,方法参数是不变的。这意味着
void-setPartner(Player-partner)
方法签名不同于
void-setPartner(Human-partner)
方法签名,即使
Human
是一个
Player
。因此,您不能像这样实现(或覆盖)



扩展类时必须小心,因为如果
Player
是一个类,并且该方法不是抽象的,而不是实际工作的方法,但是您会重载该方法,而不是重写它。

这是有道理的,因为
setPartner(Human)
setPartner(Player)
更具限制性。通过实现
Player
,您的意思是
setParner
接受任何
Player
。您的
setPartner(Human)
方法只接受子类
Human
,而不接受其他
Player
实现。

这是有意义的,因为
setPartner(Human)
setPartner(Player)
更具限制性。通过实现
Player
,您的意思是
setParner
接受任何
Player
。您的
setPartner(Human)
方法只接受子类
Human
,而不接受其他
Player
实现。

您的代码没有错误。您使用的Java版本是什么?IIRC,新版本将通过检测
人类
确实是
玩家
来支持您在这里尝试的操作。但是,旧版本将没有此功能。方法协方差从Java 5开始。@Code Guru-Nice insight。协变返回类型是在Java 1.5(又称Java 5)中引入的。@Code Guru返回类型和声明的异常可以是协变的,对吧。我没有发现您的代码有错误。您使用的是什么版本的Java?IIRC,新版本将通过检测
人类
确实是
玩家
来支持您在这里尝试的操作。但是,旧版本将没有此功能。方法协方差从Java 5开始。@Code Guru-Nice insight。协变返回类型是在Java 1.5(也称Java 5)中引入的。@Code Guru返回类型和声明的异常可以是协变的,对吧。为什么通过Player界面操纵Human会引起关注?谢谢,这正是我所需要的:)@meriton在OP的代码中?human.setPartner(robot),其中human是引用人类实例的玩家变量,robot是引用机器人实例的另一个玩家变量,它也实现了Player,这是合法的,因为Player.setPartner()接受任何玩家。但是,Human.setPartner()只接受另一个人。因此,我看到的一个问题是,无法强制实现Player的类使用自己的类作为T的类型。是否有办法解决这个问题?@user1721559否,你不能强迫它。为什么通过
播放器
界面操纵
人类
会引起关注?谢谢,这正是我需要的:)@meriton在OP的代码中?human.setPartner(robot),其中human是引用人类实例的玩家变量,robot是引用机器人实例的另一个玩家变量,它也实现了Player,这是合法的,因为Player.setPartner()接受任何玩家。然而,Human.setPartner()只接受另一个人。因此,我看到的一个问题是,没有办法强制实现Player的类使用自己的类作为T的类型。是否有办法解决这个问题?@user1721559不,您不能强制。