不确定我是否正确使用多态,如果我可以,我只能调用父级中的方法

时间:2012-02-15 17:09:08

标签: c# polymorphism

我正在进行一项多态性的作业,并且已经学习了我在c#中发现多态性的在线教程。我的第一个问题是我正确使用它。我有一个名为gameCreature的父类和两个名为agileCreature和predatorCreature的子类。我在课堂上放入虚拟和覆盖。当我使用循环打印出所有对象时,一切看起来都不错。这是代码

     gameCreature[] _creature = new gameCreature[sizeBig];
        agileCreature[] _agile = new agileCreature[size];
        predatorCreature[] _predator = new predatorCreature[size];
        for (int i = 0; i < size; i++)
        {
            _creature[i] = new gameCreature();
        }
        for (int i = size; i < sizeMid; i++)
        {
            _creature[i] = new agileCreature();
        }
        for (int i = size * 2; i < sizeBig; i++)
        {
            _creature[i] = new predatorCreature();
        }

另外,如果这是正确的。我遇到了另一个问题。我试图调用一个名为consumeCreature的方法,该方法仅在predatorCreature中,但不能调用它。我认为这是因为gameCreature中没有consumeCreature方法。除了向父级添加consumeCreature方法之外,还有另一种方法可以调用consumeCreature方法吗?这是代码。

 _creature[_creatureNum].consumeCreature(_creature[ate]);

我可以添加一些内容,因此它知道在predatorCreature中使用consumeCreature。

4 个答案:

答案 0 :(得分:1)

如果您确定_creature[_creatureNum]predatorCreature,则可以通过以下方式执行此操作:(_creature[_creatureNum] as predatorCreature).consumeCreature(_creature[ate])

请你提供更多背景知识(即,你在哪里得到_creatureNum,为什么你需要所有生物的数组?)

答案 1 :(得分:1)

在处理多态时,你正在犯一个常见的初学者错误。理想情况下,gameCreature(一组可公开访问的方法)的界面应该只包括所有生物共有的一组动作。因此,您可以使用名为consumeCreature的抽象方法,而不是使用公共Behave方法:

// Call this method to make the creature do it's thing
public abstract void Behave();

然后在predatorCreature中覆盖Behave以调用ConsumeCreature()(按惯例C#方法以大写btw开头),并且在敏捷生物中可以覆盖Behave来调用,例如RunAway() 1}}

有意义吗?

答案 2 :(得分:1)

你可以说

((predatorCreature) _creature[_creatureNum]).consumeCreature(_creature[ate]);

当且仅当_creature[_creatureNum]实际上是predatorCreature时。如果不是,你会得到一个例外。

您也可以

predatorCreature eater = (_creature[_creatureNum] as preadtorCreature);
if (eater != null) eater.consumeCreature(_creature[ate]);

的优点是它不会导致类强制转换异常。

但是强制转换通常是你没有正确使用多态的标志。一系列东西应该是你用同样方式处理的东西数组,让多态(或者包含行为类型的对象)决定项目之间应该有什么不同。

答案 3 :(得分:1)

首先,看起来您了解多态性的基础知识。 agileCreaturepredatorCreature中覆盖的方法将被虚拟调用,具体取决于该实例的动态类型

gameCreature的任何方法都应适用于所有生物,而不适用于任何一种生物。特定于某个生物的方法应该是那些派生类的方法。

当您只引用基类(predatorCreature)时,关于在特定子类(例如gameCreature)上调用方法的第二个问题 - 这是通过 upcasting 。只要类型兼容,就可以完成以下任务:

((agileCreature)(_creature[size + 1])).someAgileMethod();

我会建议不要一味地投射,因为如果这个生物确实不是agileCreature,将会发生运行时异常。更安全的方法是:

agileCreature c = _creature[size + 1] as agileCreature;
if(c != null)
{
   c.someAgileMethod();
}

这将尝试进行强制转换,如果数组索引实际上没有动态类型c,则null将为agileCreature。希望这有帮助!