我正在从PHP转到C#。
在PHP中,使用抽象类创建“级联覆盖”模式简单明了,基本上“基类方法会处理它,除非继承类有一个具有相同签名的方法“。
然而,在C#中,我花了大约20分钟尝试了各种关键字新,虚拟,抽象和< 基础和继承类中的strong>覆盖,直到我最终得到了正确的组合来执行这种简单的级联覆盖模式。
所以即使下面的代码按照我想要的方式工作,这些添加的关键字也向我建议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.";
}
}
}
答案 0 :(得分:8)
virtual
/ override
是核心多态性对;听起来你已经破解了这些
abstract
与virtual
类似,但 没有明智的基础实施;用例:可能是Stream
,其中必要用于实际实现以对字节执行某些操作。这会强制班级为abstract
new
;它破坏了多态性......最常见的情况是用更具体的签名/返回类型重新暴露(可能在密封的类中,因为它不会在链上变得更漂亮......) - 参见{{3 (vs SqlConnection.CreateCommand
),或(可能更值得注意的是)DbConnection.CreateCommand
(vs IEnumerator<T>.Current
)
答案 1 :(得分:4)
您的示例中似乎已经找到了virtual
和override
,所以:
'abstract
'也可以应用于成员而不是“virtual
”,在这种情况下,您不会直接指定方法的实现(';
'签名后)。这迫使所有具体后代实施该方法。
'new
'与继承无关,但可以在成员的后代类中使用,以隐藏基类中具有完全相同签名的成员。
简而言之;)
答案 2 :(得分:1)
继续其他答案。
当您希望允许子类执行自己的处理,不进行处理或甚至只调用函数的父类处理时,覆盖。替代或虚函数不必在后代类中实现。
摘要,当您不希望在基类中执行任何处理但希望该方法由任何继承类实现时。 (当继承类行为可能大不相同时最佳)。如果一个类只包含抽象方法,那么它实际上是一个接口类型。指定为abstract的函数必须在子类中实现(如果没有,编译器将抛出错误。)