避免使用重载mutator的instanceof

时间:2013-08-16 02:12:08

标签: java

我有两个继承自Player的类:SimplePlayer和InterleavedPlayer。

B类有以下方法:setPlayer(SimplePlayer player)和setPlayer(InterleavedPlayer player)

A类有一个Player字段,设计为SimplePlayer或InterleavedPlayer。 A类想要在这些玩家身上调用B.setPlayer(),而不关心对象所属的Player的子类。

我为子类重载了B.setPlayer(),以避免在广义的B.setPlayer(播放器播放器)方法中使用instanceof。

但是在A调用B.setPlayer()时,我得到了一个未找到符号的错误,指的是B.setPlayer(播放器)。

我应该使用哪种设计方法来解决问题? (实际上是一个玩家,因此它在理论上“知道”它传递给B的东西。但是,由于A不分青红皂白地对待它的玩家的方式,似乎只有一个玩家才有意义,而不是必须区分SimplePlayer和InterleavedPlayer。)

4 个答案:

答案 0 :(得分:4)

使用instanceof并不一定是邪恶的。像所有设计决策一样,它涉及权衡。我想这里要问的问题是,有问题的代码是否更多地与A或B结合?

例如,如果创建了一个新的Player子类,会发生什么?你需要修改B来添加一个新的setPlayer方法吗?如果是这样,在B中通过instanceof调度通用方法是有意义的,因为无论如何你都必须修改B.

答案 1 :(得分:3)

您收到错误的原因是我们没有对java中的方法参数进行运行时调度,只是在调用它的对象上。这意味着您调用它的对象的实际运行时类(B)会影响所选择的函数,但是对参数(Player)的引用的唯一编译时类会影响选择功能。

解决这个问题的答案取决于为什么B需要2个功能,如果差异可以移动到各个玩家类,如果这样做有意义。那是因为B还是因为玩家类而发生了额外的计算?

答案 2 :(得分:2)

在A:

中有重载方法
private Player;

public void setPlayer(SimplePlager player) {
    this.player = player;
    b.setPlayer(player);
}

// similar for InterleavedPlayer

或者如果调用来自构造函数,您也可以重载它。

答案 3 :(得分:1)

你需要发布代码才能修复它...你应该使用mediator,因为你在两个对象之间翻转调用。

我有两个继承自Player的类:SimplePlayer和InterleavedPlayer

确定

class Player{}
class SimplePlayer extends Player {}
class InterleavedPlayer extends Player{}

A类有一个Player字段,设计为SimplePlayer或InterleavedPlayer。 A类想要在这些玩家身上调用B.setPlayer(),而不关心对象所属的Player的子类。

确定

class A { Player field; }

我为子类重载了B.setPlayer(),以避免在广义的B.setPlayer(播放器播放器)方法中使用instanceof。

确定

class B { 
    void setPlayer(InterleavedPlayer player) {  out.println( player );  }  
}

“但是在A调用B.setPlayer()时,我得到一个未找到符号的错误,指的是B.setPlayer(播放器)。” 确定。

B需要一个交错的玩家吗? 在A中它调用B.setPlayer((InterleavedPlayer)thePlayer),将播放器转换为Interleaved播放器,你可以通过很多不同的方式解决这个问题,但没有代码可以看,它可以是很多单词....

具体地讲, 所需的代码是Player :: setPlayer和Interleaved :: setPlayer