c#不运行派生类函数
本文关键字:类函数 派生 运行 | 更新日期: 2023-09-27 18:08:03
我在制作一款游戏时遇到了问题。基本上我有很多字段,基本类型和其他类型。从逻辑上讲,我对基本字段进行了派生,以便根据需要添加额外的功能。
然而,似乎当我调用基类中存在的函数时,该函数将从基类而不是派生类运行。
下面是一些简化的代码,这样你就能明白我的意思了。public class Field
{
public Field(Field exitN, Field exitE, Field exitS, Field exitW, bool barricadeAllowed, int returnTo, int xPos, int yPos)
{
//Actual logic is in the constructor, but unrelated to the below function
}
public void Function()
{
if (this is StartField)
{
Debug.WriteLine("StartField running base function!");
}
//Actual logic here.
}
}
.
class StartField : Field
{
public StartField(Field exitN, Field exitE, Field exitS, Field exitW, string color, int xPos, int yPos)
: base(exitN, exitE, exitS, exitW, false, 0, xPos, yPos)
{
//Again, constructor emptied due to unrelatedness.
}
public new void Function()
{
Debug.WriteLine("StartField function");
//Different logic then the base function
}
在startfield对象上调用这个函数会导致"startfield运行基函数!"出现在我的调试栏中,而不是"startfield函数"。这告诉我,即使对象知道它是StartField类型,也只调用基函数。
如果有影响,所有字段都通过与其他字段的链接保存。变量要求使用字段类型,但所有变量都允许在变量中使用(因为继承)这是否会以任何方式导致调用转到"Field"代码而不是"StartField"代码(或任何其他非标准字段的代码,因为这似乎是所有字段的情况)
我能想到两种变通方法我能想到的第一个解决方法是在运行函数之前检查类型并将字段转换为它的实际类型。但是我们不允许在赋值中使用(class is Field)。此外,它将需要比简单函数调用更多的代码。
第二个解决方法也使用(class is Field)功能,即将所有字段类型功能编程到基类中。这不仅使用(类是字段),而且感觉完全错误(子应该有自己的功能,没有意义,如果基础有它的一切。不妨使用单个类,并使类型为变量而不是继承成员)
基本上,听起来你需要Function
是一个虚拟方法,这是覆盖在StartField
:
// In Field
public virtual void Function()
{
if (this is StartField)
{
Debug.WriteLine("StartField running base function!");
}
//Actual logic here.
}
// In StartField
public override void Function()
{
Debug.WriteLine("StartField function");
//Different logic then the base function
}
你当前的代码是不是使用多态性-它将始终调用Field.Function
,如果你调用Function
上的表达式的编译时类型只是Field
,因为它不是虚拟的。然后在StartField
中,你明确地说,"我不是试图覆盖基本方法-我提供了一个新的。"
查看MSDN页面的new
修饰符和virtual
修饰符的详细信息
如果将Function
设置为虚拟会怎样?
public virtual void Function()
{
if (this is StartField)
{
Debug.WriteLine("StartField running base function!");
}
//Actual logic here.
}
然后在StartField
中重写,像这样:
public override void Function()
{
Debug.WriteLine("StartField function");
//Different logic then the base function
}
绝对不要试图绕过这个——这是基本的OOP。
您需要将基类方法标记为虚拟(或抽象,如果它没有自己的逻辑),以便可以覆盖它。然后将子类方法标记为覆盖。例如,查看http://msdn.microsoft.com/en-us/library/ebca9ah3(v=vs.110).aspx