如何将多态对象作为派生对象传递?

为了简单起见,我有两个类:ActionTaken和MovementTaken. MovementTaken是一个派生类ActionTaken。我有一个Queue完整的动作,每个动作都有一个char决定动作类型的。(每个动作都有一个正确的类型)我想将 的元素传递Queue给一个函数,该函数专门与一个MovementTaken参数一起工作,但是由于我使用多态性,所以参数是 type ActionTaken,但是我不能使用来自 的成员变量MovementTaken,但是不要不存在于ActionTaken. 但是如果我将 functionactivateMovement的参数设置为 type MovementTaken,我相信会有一个错误,说你不能将基类型转换为派生类型。这是代码:


public abstract class ActionTaken : MonoBehaviour

{

    public char type;

    public Transform minionTakingAction;

}


public class MovementTaken : ActionTaken

{

    public int targetTileH;

    public int targetTileV;

    public MovementTaken(Transform _minionTakingAction, int _targetTileH, int _targetTileV)

    {

        type = 'M';

        minionTakingAction = _minionTakingAction;

        targetTileH = _targetTileH;

        targetTileV = _targetTileV;

    }

}


Queue<ActionTaken> actionTaken;

public void activateMovement(ActionTaken toActivate)

{//some code using toActivate's members targetTileH and targetTileV}


哈士奇WWW
浏览 130回答 2
2回答

眼眸繁星

如果您知道传递给该方法的参数是一个MovementTaken实例,则可以将其向下转换:public void activateMovement(ActionTaken toActivate){&nbsp; &nbsp; MovementTaken casted = toActivate as MovementTaken;&nbsp; &nbsp; // Do something with casted.targetTileH and/or caster.targetTileV

FFIVE

Abstract类的优点是定义基本实现,或强制派生类型进入实现细节:public abstract class ActionTaken : MonoBehaviour{&nbsp; &nbsp; public char Type { get; protected set; }&nbsp; &nbsp; public Transform Target { get; }&nbsp; &nbsp; // base ctor&nbsp; &nbsp; protected ActionTaken(Transform target)&nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; Type = '\0';&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; Target = target;&nbsp; &nbsp; }&nbsp; &nbsp; // Force implementation onto sub class&nbsp; &nbsp; public abstract void Activate();}public class MovementTaken : ActionTaken{&nbsp; &nbsp; public int TileH { get; set; }&nbsp; &nbsp; public int TileV { get; set; }&nbsp; &nbsp; public MovementTaken(Transform target, int tileH, int tileV)&nbsp; &nbsp; &nbsp; &nbsp; : base(target)&nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; Type = 'M';&nbsp; &nbsp; &nbsp; &nbsp; TileH = tileH;&nbsp; &nbsp; &nbsp; &nbsp; TileV = tileV;&nbsp; &nbsp; }&nbsp; &nbsp; public override void Activate()&nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; //some code using TileH and TileV&nbsp; &nbsp; }}因此,您的调用代码将是:Queue<ActionTaken> actionTaken;public void activateMovement(ActionTaken action){&nbsp; &nbsp; action.Activate();}我也不确定Type它的用途,但如果你仍然需要它,最好在每个类中定义一个常量,ActionTaken如果你有更多的话。如果你最终Queue<ActionTaken>用各种派生的运动类型填充你的,这可能是有意义的。否则,您的ActivateMovement方法可能最终会成为一个冗长的switch声明。接口在这里也可能是有利的:public interface IActionTaken{&nbsp; &nbsp; Transform Target { get; }&nbsp; &nbsp; void Activate();}然后您将替换您的队列: Queue<IActionTaken> Actions调用队列中所有动作的代码可以非常简单:while(Actions.Count > 0){&nbsp; &nbsp; IActionTaken current = Actions.Dequeue();&nbsp; &nbsp; current.Activate();}
打开App,查看更多内容
随时随地看视频慕课网APP