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不,您不能强制。