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 ?
对于糟糕的实践,预期会有糟糕的解决方法。我一般不会使用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
版本。