我正在从PHP迁移到C#.
在PHP中,使用抽象类来创建" 级联覆盖 "模式是简单而直接的,基本上" 基类方法将处理它,除非继承类具有具有相同签名的方法 ".
然而,在C#中,我花了大约20分钟在基础和继承类中尝试关键字new,virtual,abstract和override的各种组合,直到我最终得到了正确的组合来执行这种简单的级联覆盖模式.
因此,即使下面的代码按照我想要的方式工作,这些添加的关键字也向我建议C#可以用抽象类做更多的事情.我已经查找了这些关键字的示例,并基本了解它们的作用,但仍然无法想象除了这种简单的"级联覆盖"模式之外我会使用它们的真实场景.什么是一些现实世界中,你实现你的一天到一天的节目这些关键字的方法呢?
有效的代码:
using System;
namespace TestOverride23433
{
public class Program
{
static void Main(string[] args)
{
string[] dataTypeIdCodes = { "line", "wn" };
for (int index = 0; index < dataTypeIdCodes.Length; index++)
{
DataType dataType = DataType.Create(dataTypeIdCodes[index]);
Console.WriteLine(dataType.GetBuildItemBlock());
}
Console.ReadLine();
}
}
public abstract class DataType
{
public static DataType Create(string dataTypeIdCode)
{
switch (dataTypeIdCode)
{
case "line":
return new DataTypeLine();
case "wn":
return new DataTypeWholeNumber();
default:
return null;
}
}
//must be defined as virtual
public virtual string GetBuildItemBlock()
{
return "GetBuildItemBlock executed in the default datatype class";
}
}
public class DataTypeLine : DataType
{
public DataTypeLine()
{
Console.WriteLine("DataTypeLine just created.");
}
}
public class DataTypeWholeNumber : DataType
{
public DataTypeWholeNumber()
{
Console.WriteLine("DataTypeWholeNumber just created.");
}
//new public override string GetBuildItemBlock() //base method is erroneously executed
//public override string GetBuildItemBlock() //gets error "cannot override inherited member because it is not marked virtual, abstract, or override"
public override string GetBuildItemBlock()
{
return "GetBuildItemBlock executed in the WHOLENUMBER class.";
}
}
}
Run Code Online (Sandbox Code Playgroud)
virtual/ override是核心多态性对; 听起来你已经破解了这些
abstract像virtual,但就是没有合理的基本实现; 用例:也许是Stream,它是需要实际实现做字节的东西.这迫使班级成为abstract
new通常应该避免; 它破坏了多态性...最常见的情况是用更具体的签名/返回类型重新暴露(可能在密封的类中,因为它不会在链上变得更漂亮......) - 看SqlConnection.CreateCommand(vs DbConnection.CreateCommand) ,或(或许更值得注意)IEnumerator<T>.Current(vs IEnumerator.Current)