2012-10-04 48 views
1

对不起,我有错误代码之前...奇怪的接口实现

所以我有,看起来像一个接口:

public interface Player { 
    void setPartner(Player partner); 
} 

而且我有一个接口,它看起来像这样的实现:

public class Human implements Player 
{ 
    private Human partner; 

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

所以编译器说,我不是从实现每一个玩家的方法指示给我,我要的setPartner方法的参数类型完全匹配,即使你呃一个人,是一个球员。有没有什么好的方法来解决这个问题,或者以不同的方式实施?

+0

我的代码没有出错。 –

+3

您使用的是什么版本的Java? IIRC,新版本将通过检测“Human”确实是一个“Player”来支持您在此尝试做的事情。但是,旧版本不具备此功能。 –

+3

方法协方差以Java 5开头。 –

回答

2

您不能有协变参数(如果通过播放器界面操作您的Human实例会发生什么?),但是您可以使用泛型。

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; 
    } 
} 

但是,你不能强制执行类实际使用它自己的类型,播放器的类型参数。

+0

为什么通过'Player'操作''Human'会引起担忧? – meriton

+0

感谢这正是我需要:) – user1721559

+0

@meriton在OP的代码? human.setPartner(robot)其中,human是引用人类实例的Player变量,另一个引用Robot实例的机器人变量Player也是合法的,因为Player.setPartner()带有任何播放器。但是,Human.setPartner()只会使用另一个Human。 –

3

在Java中,方法参数是不变的。这意味着void setPartner(Player partner)方法签名与void setPartner(Human partner)方法签名不同,即使Human是-a Player。所以你不能像那样实现(或覆盖)。

如果Player是一个类,并且该方法不是抽象的,而是重载该方法而不是重写它,则必须小心扩展类。

1

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