c# - 如何调用顶级构造函数?

标签 c# class inheritance xna

我希望我能正确解释这个问题,这让我有点困惑。

我一直在研究类似于 flixel 的游戏库,但使用 C# 的 XNA 框架而不是 Flash。现在当前的类布局是这样的。

ClxBasic -> ClxObject -> ClxSprite

每个类都有一个构造函数,并为它下面的类调用构造函数。我使用此代码来执行此操作。

namespace Test
{
    public class ClxBasic
    {
        public ClxBasic()
        {
            Constructor();
        }

        public void Constructor()
        {
            DoSomething();
        }
    }

    public class ClxObject : ClxBasic
    {
        public ClxObject() : base()
        {
            Constructor();
        }
            public void Constructor()
            {
                    DoSomething();
            }
    }

    public class ClxSprite : ClxObject
    {
        public ClxSprite() : base()
        {
            Constructor();
        }
            public void Constructor()
            {
                    DoSomething();
            }
    }
}

所以基本上,当我创建一个新的 ClxSprite 时,它​​会调用 ClxSprite 构造函数,然后是它下面的所有构造函数(ClxObject 和 ClxBasic)。

我确信有一种更简单的方法可以做到这一点,我洗耳恭听。

然而,我更大的问题实际上是如何正确地派生和覆盖其他类的方法。

问题是,当创建一个从 ClxSprite 扩展的类时,例如,当调用从最基本类(ClxBasic)重写的方法时,它只会调用底部方法而不是顶部方法。

我需要这样做的原因是因为我有一个全局类,它通过将自己添加到 ClxBasic 构造函数中的列表来控制从 ClxBasic 派生的所有对象。

这是一些示例代码。

namespace Test
{
    public static class ClxG()
    {
        public static List<ClxBasic> GlobalObjects; //All objects will be added here by the ClxBasic constructor
            ClxSprite test = new ClxSprite();
            GlobalObjects.Add(test);
        public static Update()
        {
            foreach(ClxBasic basic in GlobalObjects)
                basic.Update(); //Calling this calls ClxBasic.Update() when it should call ClxSprite.Update()
        }
    }
}

当调用 basic.Update() 时,它会转到底部更新,即位于 ClxBasic 中的那个,尽管对象是 ClxObject 或 ClxSprite 或其他派生类。

我也有一个有限的修复,通过在 foreach 循环中将 ClxBasic 更改为 ClxSprite,您可以正确调用该类的构造函数方法。但是,当基于覆盖方法的库创建自定义类时,将调用较低的更新。

但是,限制是你不能添加我没有专门计划的类(class)。例如,如果我要从 ClxSprite 派生一个类 Player 并覆盖 Update() 方法,它会被添加到 GlobalObjects 列表中,但是,永远不会调用它的更新,它将达到最高的是 ClxSprite 的。

希望它的工作方式是,在 Game1.cs 中,我希望能够将 FlxG.Update() 放入 Game.Update() 循环中并能够创建对象并让我的框架处理其余部分。

我希望我说得有点道理,整个事情感觉像是某种继承的开始,有点让我的大脑受伤。

最佳答案

要同时调用基类方法作为子类实现的一部分,您可以这样做:

class Base {
  public virtual void Method() {
    // ...
  }
}

class Derived : Base {
  public override void Method() {
    base.Method();
    // ....
  }
}

class Derived2 : Derived {
  public override void Method() {
    base.Method();
    // ....
  }
}

但是子方法不是必需的来调用基础方法。

另一方面,构造函数总是需要(最终)调用基础构造函数。

现在,如果您希望基类方法始终作为某些处理的一部分被调用,您可以使用template method pattern .基本上你的基类有一个非虚拟方法来驱动调用虚拟(或抽象)方法的算法;子类可以重写以创建自己的版本。

关于c# - 如何调用顶级构造函数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11169536/

相关文章:

c# - 在 C# winform 中如何识别应用程序显示在哪个监视器上

c# - 如何为泛型创建一个完全懒惰的单例

Java 类 - 当我读到部门时主要不编译

java - boolean.isInstance(true) 是假的?

c++ - 这是测试两条线是否共线的正确方法吗?

c# - 学习WM6的书籍

c# - 在 .NET 中实现加密/解密流的正确方法?

ios - Swift 3 (SpriteKit) 从自定义类中将子项添加到 GameScene

java - 多个继承类,它们必须在单独的文件中吗?

C++ 继承 - 覆盖函数,包括使用 "::"s、.h 文件和 .cpp 文件