1

我正在制作的游戏有问题。基本上我有很多字段,一个基本类型和其他类型。从逻辑上讲,我制作了基本字段的衍生产品,以根据需要添加额外的功能。

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

这是一些精简的代码,因此您可以了解我的意思。

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 running base function!” 出现在我的调试栏中,但不是“startfield 函数” 这告诉我只有基函数被调用,即使对象知道它是 StartField 类型。

如果有任何不同,所有字段都通过与其他字段的链接保存。变量要求字段类型,但所有变量都允许在变量中(因为继承)这是否会以任何方式导致调用转到“字段”代码而不是“开始字段”代码(或任何其他非标准的代码字段,因为这似乎是所有字段的情况)

我能想到两种解决方法我能想到的第一种解决方法是在运行函数之前检查类型并将字段转换为它的实际类型。但是我们不允许在作业中使用 (class is Field)。另外,它需要比简单函数调用更多的代码。

第二种解决方法还使用(类为字段)功能,即将所有字段类型功能编程到基类中。它不仅使用(类是字段)而且感觉完全错误(孩子应该有自己的功能,如果基础拥有一切就没有意义。还不如使用单个类并将类型作为变量而不是继承成员)

4

3 回答 3

4

基本上,听起来您需要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是 just ,它将始终调用Field,因为它不是虚拟的。然后StartField你明确地说,“我不是要覆盖基本方法 - 我正在提供一个新方法。”

有关更多详细信息,请参阅修饰符的MSDN页面和new修饰符virtual页面。

于 2013-04-08T22:06:13.167 回答
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
}
于 2013-04-08T22:06:16.347 回答
2

绝对不要试图解决这个问题——这是基本的 OOP。

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

于 2013-04-08T22:07:42.760 回答