OOP基础知识:从派生类创建基函数中覆盖的对象

本文关键字:基函数 覆盖 对象 创建 基础知识 派生 OOP | 更新日期: 2023-09-27 17:51:18

不好意思,我的英文不是很好。
假设下面的代码(在程序模式下使用LINQPad进行测试):

public class BaseClass
{
    protected Settings settings;
    public BaseClass()
    {
        this.settings = new Settings();
    }
    public virtual void PrintSettings()
    {
        var t = settings.GetType();
        Console.WriteLine(string.Join(", ", t.GetProperties().Select(pi => pi.Name)));
    }
    public class Settings
    {
        public string BaseClassSetting { get { return "BaseClassSetting."; } }
    }
}

调用"new BaseClass(). printsettings();"显然会在控制台输出"BaseClassSetting"。
让我们从BaseClass中派生一个类:

public class InheritedClass : BaseClass
{
    public new class Settings : BaseClass.Settings
    {
        public string InheritedClassSetting { get { return "InheritedClassSetting!"; } }
    }
}

调用"new InheritedClass(). printsettings();"仍然会在控制台中打印"BaseClassSetting"。
使代码使用"新"继承类的唯一方法。设置是通过添加像

这样的元素来实现的。
public InheritedClass()
{
    this.settings = new Settings();
}

使用这个额外的元素,它将所需的"InheritedClassSetting, BaseClassSetting"打印到控制台。
现在的问题是:是否有可能使baseclass - actor始终使用实例对象的Settings-Class ?

OOP基础知识:从派生类创建基函数中覆盖的对象

对于糟糕的实践,预期会有糟糕的解决方法。我一般不会使用new关键字,更不用说嵌套类了。通过让基类接受继承自BaseClass.Settings的泛型类型并使用无参数构造函数,可以删除继承类中的构造函数。很明显,这是不可读的

public class BaseClass<T> where T : BaseClass<T>.Settings, new()
{
    protected Settings settings;
    public BaseClass()
    {
        settings = new T();
    }
    public virtual void PrintSettings()
    {
        var t = settings.GetType();
        Console.WriteLine(string.Join(", ", t.GetProperties().Select(pi => pi.Name)));
    }
    public class Settings
    {
        public string BaseClassSetting
        {
            get { return "BaseClassSetting."; }
        }
    }
}
public class InheritedClass : BaseClass<InheritedClass.Settings>
{
    public new class Settings : BaseClass<InheritedClass.Settings>.Settings
    {
        public string InheritedClassSetting
        {
            get { return "InheritedClassSetting!"; }
        }
    }
}

注意这一行:

public new class Settings : BaseClass<InheritedClass.Settings>.Settings

泛型的参数不需要指定InheritedClass。我添加它是因为它已经很混乱了,我不想让它变得更糟。

不能,因为你不能有"虚拟类型"。

有几种方法可以尝试实现您在这里所做的事情,但是所有这些方法都需要InheritedClass在某些时候显式地引用自己的Settings版本。