2

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

B类有这些方法:setPlayer(SimplePlayer player)和setPlayer(InterleavedPlayer player)

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

我为子类重载了 B.setPlayer() 以避免在通用的 B.setPlayer(Player player) 方法中使用 instanceof。

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

我应该在这里使用什么设计方法来解决问题?(A 实际上创建了玩家,所以理论上它“知道”它传递给 B 的内容。但是,由于 A 不分青红皂白地对待它的玩家的方式,让一个玩家做事似乎是有意义的,而不是必须区分 SimplePlayer 和 InterleavedPlayer)。

4

4 回答 4

4

使用 instanceof 不一定是坏事。像所有设计决策一样,它涉及权衡。我想这里要问的问题是,有问题的代码是与 A 还是 B 更耦合?

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

于 2013-08-16T02:16:20.817 回答
3

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

解决这个问题的答案取决于为什么 B 需要 2 个函数,以及是否可以将差异转移到各个玩家类中,以及这是否具有设计意义。即额外的计算是因为B还是因为玩家类而发生的?

于 2013-08-16T02:20:15.863 回答
2

在 A 中有重载方法:

private Player;

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

// similar for InterleavedPlayer

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

于 2013-08-16T02:22:15.277 回答
1

您需要发布代码才能修复它...您应该使用调解器,因为您正在两个对象之间进行调用。

我有两个继承自 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(Player player) 方法中使用 instanceof。

好的

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

“但在 A 调用 B.setPlayer() 时,我收到一个符号未找到错误,指的是 B.setPlayer(Player)。” 好的。

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

特别是,需要的代码是 Player::setPlayer 和 Interleaved::setPlayer

于 2013-08-16T02:29:57.443 回答