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

本文关键字:调用 方法 如果 正确地 是否 不确定 多态性 | 更新日期: 2023-09-27 18:24:56

我正在做一项关于多态性的作业,并遵循了我在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();
        }

此外,如果这是正确的。我遇到了另一个问题。我试图调用一个名为consumerCreature的方法,它只在predatorCreature中,但不能调用它。我认为这是因为在gameCreature中没有consumerCreaure方法。除了在父对象中添加consumerCreature方法外,还有其他方法可以调用consumerCreaturemethod吗?这是它的代码。

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

我能给它添加一些东西吗,这样它就知道在捕食者中使用consumerCreature了。

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

如果您确定_creature[_creatureNum]predatorCreature,您可以按以下方式执行:(_creature[_creatureNum] as predatorCreature).consumeCreature(_creature[ate])

你能提供更多的背景吗(即,你从哪里得到这个_creatureNum,为什么你需要所有生物的阵列)?

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

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

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

有道理吗?

你可以说

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

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

你也可以做

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

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

但类型转换通常是你没有正确使用多态性的标志。一个数组应该是一个以相同方式处理的数组,并让多态性(或者可能是一个包含的行为类型对象)决定项目之间应该有什么不同。

首先,您似乎了解了多态性的基本知识。在agileCreaturepredatorCreature中重写的方法将被调用,这实际上取决于该实例的动态类型

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

您的第二个问题是,当您只有基类(gameCreature)的引用时,调用特定子类(如predatorCreature)上的方法-这是通过upcast完成的。只要类型兼容,就可以执行以下操作:

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

不过,我建议不要盲目施法,因为如果这个生物确实不是agileCreature,就会出现运行时异常。更安全的方法是:

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

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