[英]Issue with polymorphism and class hierarchy for objects in RTS game
我正在用Java編寫RTS游戲並遇到了一些多態問題。 為了描述我的問題,我將在游戲中列出一些對象/類:(我將在括號內說明每個對象/類應該做什么)
在我眼中這樣做的理想方式是每個獨特能力的類別,即Movable,Attackable,Farmable,Constructible。 這是所有列出的對象具有的不同能力。 它們都是GameObject(層次結構中的最高級別,包含所有對象的公共數據)。
Movable保存用於移動物體的所有代碼(計算速度,方向,新位置等)。 Attackable持有跟蹤目標,射擊,更新射擊等的代碼。其他能力類也是如此。
所以在我看來這將是完美的:
public class Tank extends Movable, Attackable, GameObject {}
public class Tiger extends Movable, Attackable, Farmable, GameObject {}
顯然,Java不允許擴展多個類。 我不知道如何使用接口來解決我的多態性和類層次結構問題。
有任何想法嗎? 目標當然不是重復游戲中幾個對象共享的代碼。
Movable , Attackable是對象的各種可能行為,因此它們更適合作為接口 。
至於這些行為的實現 - 為了解決重復代碼的問題,你可以為每個行為設置單獨的類 - 讓它們命名為服務 - 例如。 MoveService , AttackService 。
然后,您可以將這些服務注入您正在創建的對象(例如, 新的Tank(myMoveService) )或將對象傳遞給這些服務,例如。 MoveService.instance()。移動(myTank)
您可以通過調用委托方法為每個類運行一些自定義代碼。
例
interface Movable { public void onMove(); }
class Tank implements Movable {
public void onMove() {
//tank moved!
}
}
class MoveService {
public void move(Movable m) {
// do what you need to do to move
// invoke custom code by running a delegate method
m.onMove();
}
}
我會建議接口和組合的組合。 這是一個工廠的例子,它使用泛型來保存一些代碼。
interface UnitFactory<U extends Unit> {
public U newUnit();
}
abstract class UnitFactoryBuilding<U, F extends AbstractUnitFactory<U>>
extends Building // assume 'Building extends GameObject'
implements UnitFactory<U> {
final F factory;
UnitFactoryBuilding(F factory) {
this.factory = factory;
}
MapPosition getExitPoint() {
/* return the point for the 'door' on the model */
}
@Override
public U newUnit() {
U unit = factory.newUnit();
/* assume Building has a method that
* returns the player that 'owns' it
*/
getPlayer().deductResources(unit.getResourceCost());
return unit;
}
}
abstract class AbstractUnitFactory<U>
implements UnitFactory<U> {
final Building owner;
AbstractUnitFactory(Building owner) {
this.owner = owner;
}
MapPosition getPositionForNewUnit() {
return owner.getExitPoint();
}
}
class TankFactory
extends AbstractUnitFactory<Tank> {
TankFactory(TankFactoryBuilding owner) {
super(owner);
}
@Override
public Tank newUnit() {
return new Tank(getPositionForNewUnit());
}
}
class TankFactoryBuilding
extends UnitFactoryBuilding<Tank, TankFactory> {
TankFactoryBuilding() {
super(new TankFactory(this));
}
}
它有點復雜,但是類似的東西讓你可以保持你的實現分離,而不必復制大量的代碼。 創建一種新的Factory只需要編寫最后兩個類。
您不必使用泛型來做這種事情,但它使得它很方便,因為TankFactoryBuilding
可以作為TankFactory
訪問其factory
成員。
Movable和Attackable只是屬性。
考慮一個具有“隱身”能力的單位,它在隱身時不會受到攻擊,但可能在不隱身時受到攻擊。
對象樹是關於行為的。
諸如Terrain,Unit,Building等類更有意義,因為它們具有大致相似的行為。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.