2013-04-08 103 views
1

我遇到了一个我正在制作的游戏的问题。 基本上我有很多领域,基本类型和其他类型。 从逻辑上讲,我制作了基本字段的衍生物,以根据需要添加额外的功能。C#没有运行派生类函数

但是,似乎当我调用基类中存在的函数时,该函数将从基类而不是派生类运行。

这里有一些缩减的代码,所以你可以看到我的意思。

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”代码(或任何其他非代码标准的现场,因为这似乎是所有场的情况下)

有2个解决方法我能想到的 第一个解决方法我能想到的是检查的种类和铸造领域它运行函数之前的实际类型。 但我们不允许在作业中使用(班级是Field)。此外,它需要更多的代码,然后需要一个简单的函数调用。

第二个解决方法还使用(类是Field)功能,即将所有字段类型功能编程到基类中。 它不仅使用(类是Field),而且只是感觉明显错误(孩子应该有自己的功能,如果基地拥有所有功能,这是没有意义的。也可以使用单个类并且类型为a变量,而不是一个继承部件)

+0

你为什么要在基类中检查实例?在StarField类上覆盖函数,并将所有关于StarField类的逻辑放在那里。 – 2013-04-08 22:05:20

+0

你如何调用'Function'?运行'(新的StartField).Function()'应该按预期工作。 – 2013-04-08 22:06:18

回答

3

如果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 
} 
+0

谢谢,这完美的作品。 – Chirimorin 2013-04-08 22:12:01

3

基本上,它听起来像您需要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的表达式的le-time类型只是Field,因为它不是虚拟的。然后,在StartField中,您明确地说,“我不想重写基本方法 - 我正在提供一个新方法。”

查看MSDN page for the new modifierthe one on the virtual modifier了解更多详情。

+0

argh ..秒杀我! – 2013-04-08 22:06:42

+0

@retailcoder你是正确的,第二无关紧要) – 2013-04-08 22:08:16

+0

我不能标记两个答案,虽然:( – Chirimorin 2013-04-08 22:16:27

2

绝对不要尝试解决这一点 - 这是基本的OOP。

您需要将基类方法标记为虚拟(或抽象,如果它没有自己的逻辑),以便可以覆盖它。然后将子类方法标记为覆盖。例如,检查http://msdn.microsoft.com/en-us/library/ebca9ah3(v=vs.110).aspx

+0

我并没有试图解决问题,我可能有但是像你说的那样,这不是OOP。 – Chirimorin 2013-04-08 22:17:08

+1

+1的准确性。没有代码,但准确。 – 2013-04-08 22:24:12

+1

@retailcoder:谢谢 - 我认为这个概念比问题中的特定代码示例更重要。 – 2013-04-08 22:50:56