简体   繁体   English

避免使用重载mutator的instanceof

[英]Avoiding instanceof with overloaded mutators

I have two classes that inherit from Player: SimplePlayer and InterleavedPlayer. 我有两个继承自Player的类:SimplePlayer和InterleavedPlayer。

Class B has these methods: setPlayer(SimplePlayer player) and setPlayer(InterleavedPlayer player) B类有以下方法:setPlayer(SimplePlayer player)和setPlayer(InterleavedPlayer player)

Class A has a Player field, which is designed to be either a SimplePlayer or InterleavedPlayer. A类有一个Player字段,它被设计为SimplePlayer或InterleavedPlayer。 Class A wants to call B.setPlayer() on these players, without concerning itself with what subclass of Player the object is. A类想要在这些玩家上调用B.setPlayer(),而不关心对象所属的Player的子类。

I overloaded B.setPlayer() for the subclasses in order to avoid using instanceof in a generalized B.setPlayer(Player player) method. 我为子类重载了B.setPlayer(),以避免在广义的B.setPlayer(播放器播放器)方法中使用instanceof。

But on A's call to B.setPlayer(), I get a symbol not found error referring to B.setPlayer(Player). 但是在A调用B.setPlayer()时,我得到一个未找到符号的错误,指的是B.setPlayer(Player)。

What design approach should I use here to resolve the issue? 我应该在这里用什么设计方法来解决问题? (A actually creates the players, so it in theory "knows" what it's passing to B. However, because of the way A indiscriminately treats it's player it seems to make sense just having a Player that it does stuff to, rather than having to distinguish between SimplePlayer and InterleavedPlayer). (实际上是一个玩家,因此它在理论上“知道”它传递给B的东西。但是,由于A不分青红皂白地对待它的玩家的方式,似乎只有一个玩家才有意义,而不是必须区分SimplePlayer和InterleavedPlayer)。

Using instanceof is not necessarily evil. 使用instanceof并不一定是邪恶的。 Like all design decisions, it involves a trade off. 像所有设计决策一样,它涉及权衡。 I think the question here to ask is, is the code in question more coupled with A or B? 我想这里要问的问题是,有问题的代码是否更多地与A或B相结合?

For example, what happens if a new subclass of Player is created? 例如,如果创建了一个新的Player子类,会发生什么? Will you have to modify B to add a new setPlayer method? 你需要修改B来添加一个新的setPlayer方法吗? If so, it makes sense to have a generic method in B that dispatches via instanceof since you'll have to modify B anyway. 如果是这样,在B中通过instanceof调度通用方法是有意义的,因为无论如何你都必须修改B.

The reason you are getting the error is that we do not have run time dispatching on the method parameters in java, just on the object on which it is being called. 您收到错误的原因是我们没有对java中的方法参数进行运行时调度,只是在调用它的对象上。 Meaning that the actual run-time class of the object you call it on ( B ) affects which function is picked, however the only the compile time class of the reference to the parameter ( Player ) affects the choice of function. 这意味着您调用它的对象的实际运行时类( B )会影响选择哪个函数,但是参数( Player )的唯一编译时类会影响函数的选择。

The answer to fix this would depend on why B needs 2 functions, and if the difference can be moved into the individual player classes , and if that makes design sense. 解决这个问题的答案将取决于为什么B需要2个函数,以及是否可以将差异移动到各个玩家类中 ,以及这是否具有设计意义。 ie the does the extra computation happen because of B or because of the player classes? 即由于B或由于玩家类别而发生额外的计算?

Have overloaded methods in A: 在A中有重载方法:

private Player;

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

// similar for InterleavedPlayer

Or if the call comes from within the constructor, you can overload that too. 或者,如果调用来自构造函数,您也可以重载它。

you'll need to post code to get it fixed... You should use mediator, because you are flip-flopping calls between two objects. 你需要发布代码才能修复它...你应该使用mediator,因为你是在两个对象之间翻转调用。

I have two classes that inherit from Player: SimplePlayer and InterleavedPlayer 我有两个继承自Player的类:SimplePlayer和InterleavedPlayer

ok

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

Class A has a Player field, which is designed to be either a SimplePlayer or InterleavedPlayer. A类有一个Player字段,它被设计为SimplePlayer或InterleavedPlayer。 Class A wants to call B.setPlayer() on these players, without concerning itself with what subclass of Player the object is. A类想要在这些玩家上调用B.setPlayer(),而不关心对象所属的Player的子类。

ok

class A { Player field; }

I overloaded B.setPlayer() for the subclasses in order to avoid using instanceof in a generalized B.setPlayer(Player player) method. 我为子类重载了B.setPlayer(),以避免在广义的B.setPlayer(播放器播放器)方法中使用instanceof。

ok

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

"But on A's call to B.setPlayer(), I get a symbol not found error referring to B.setPlayer(Player)." “但是在A调用B.setPlayer()时,我得到一个未找到符号的错误,指的是B.setPlayer(播放器)。” ok. 好。

B requires an interleaved player right? B需要一个交错的玩家吗? in A where it calls B.setPlayer( (InterleavedPlayer) thePlayer ), cast the Player to an Interleaved player, you can get around this a lot of different ways but without code to see, it can be a lot of words.... 在A中它调用B.setPlayer((InterleavedPlayer)thePlayer),将播放器转换为Interleaved播放器,你可以通过很多不同的方式解决这个问题,但没有代码可以看,它可以是很多单词....

particularly, the code needed is Player::setPlayer, and Interleaved::setPlayer 特别是,所需的代码是Player :: setPlayer和Interleaved :: setPlayer

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM