我有这些接口:
public interface IShipOwner {}
public interface ICitizen {}
public interface IPlayer extends ICitizen, IShipOwner {}
public interface IAIPlayer exends IPlayer {}
此外,我在同一类中有这两种方法:
public boolean isHumanPlayer(ICitizen citizen) {
if (citizen instanceof IPlayer) {
if (citizen instanceof IAIPlayer) {
return false;
} else {
return true;
}
}
return false;
}
public boolean isHumanPlayer(IShipOwner shipOwner) {
if (shipOwner instanceof IPlayer) {
if (shipOwner instanceof IAIPlayer) {
return false;
} else {
return true;
}
}
return false;
}
使用isHumanPlayer
类型的对象调用IPlayer
时,我必须将其强制转换为ICitizen
或IShipOwner
,以明确应该调用哪种方法。< / p>
从客户角度调用这些方法的最佳方法是什么?如果可能的话,我确实希望避免在保留方法重载的同时强制转换参数。
IShipOwner
都是IShipOwner
,也要让公民实施ICitizen
,反之亦然。答案 0 :(得分:2)
测试对象的功能是代码味道。这意味着您没有使用语言中内置的OO功能。您应该完全摆脱isHumanPlayer
方法。然后,无论您在哪里测试isHumanPlayer
并根据结果执行不同的操作,只需在IPlayer
上调用一个根据实现执行不同操作的方法。
我的建议:
interface Player
- 常见的行为就在这里,包括根据isHumanPlayer
的价值为您做的任何事情的方法。interface HumanPlayer extends Player
- 添加仅与人类玩家相关的方法。interface AiPlayer extends Player
- 添加仅与AI玩家相关的方法。 HumanPlayer
和AiPlayer
添加的方法只能由您的程序部分调用,这些部分专门处理玩家 人类或AI玩家。你应该很少发现必须施展。如果这样做,您在转换对象上调用的方法可能需要向上移动。
根据您描述的现有层次结构,听起来像人类和AI玩家都是ShipOwner
。但ShipOwner
界面的确切位置取决于是否存在Player
不是ShipOwner
的任何其他ShipOwner
,或者不是Player
的任何类型call “$(WIX)bin\heat.exe” dir "C:\MyProjectPath\bin\Release" -dr APPLICATIONROOTDIRECTORY -cg ApplicationComponents -gg -g1 -scom -sreg -sfrag -srd -suid -var var.sourcePath -out “$(ProjectDir)Fragments\MainAppFiles.wxs” -t $(ProjectDir)Transform.xslt
{1}}。
答案 1 :(得分:1)
我是Kevin Krumwiede的第二个观点。
但如果你真的 必须 保留isHumanPlayer()
,那么:
让公民实施IShipOwner即使不是每个IShipOwner都是ICitizen,反之亦然。
没有。决不。 “如果你去,你会发现只有痛苦。”
使用不同的方法名称。
那会有效,但这无异于接受失败,对吗?
我没想到的其他事情。
这将我们带到:
添加isHumanPlayer( IPlayer player )
提出一个新接口,由所有其他接口扩展,可能是IPerson
。
使isHumanPlayer()
成为每个界面的一部分。所以,人类玩家只会返回true
;其他人只需返回false
。
另请注意这一整个混乱:
public boolean isHumanPlayer(ICitizen citizen) {
if (citizen instanceof IPlayer) {
if (citizen instanceof IAIPlayer) {
return false;
} else {
return true;
}
}
return false;
}
可以重述如下:
public boolean isHumanPlayer(ICitizen citizen)
{
return citizen instanceof IPlayer && !(citizen instanceof IAIPlayer);
}
(这可能也可能不是你的初衷。)