我有两个继承自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。)
答案 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