不确定我是否正确地使用了多态性,如果是,我只能调用父级中的方法
本文关键字:调用 方法 如果 正确地 是否 不确定 多态性 | 更新日期: 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]);
它的优点是不会导致类强制转换异常。
但类型转换通常是你没有正确使用多态性的标志。一个数组应该是一个以相同方式处理的数组,并让多态性(或者可能是一个包含的行为类型对象)决定项目之间应该有什么不同。
首先,您似乎了解了多态性的基本知识。在agileCreature
或predatorCreature
中重写的方法将被调用,这实际上取决于该实例的动态类型。
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
。希望这能有所帮助!