抽象 new/virtual/override/abstract 关键字的真实示例有哪些?
我将从 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.";
}
}
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
virtual
/override
是核心多态对; 听起来你已经破解了这些abstract
就像virtual
,但是没有没有合理的基础实现; 用例:可能是一个Stream
,其中实际实现需要对字节执行某些操作。 这迫使类成为抽象
new
通常应该避免; 它破坏了多态性...最常见的情况是使用更具体的签名/返回类型重新公开(可能在密封类中,因为它在链上不会变得更漂亮...) - 请参阅SqlConnection.CreateCommand
(与DbConnection.CreateCommand
),或者(也许更值得注意)IEnumerator
(与
IEnumerator.Current
)virtual
/override
is the core polymorphism pair; sounds like you've already cracked theseabstract
is likevirtual
, but there is no sensible base implementation; use-cases: perhaps aStream
, where it is necessary for the actual implementation to do something with the bytes. This forces the class to beabstract
new
should usually be avoided; it breaks polymorphism... the most common case is to re-expose with a more specific signature / return-type (perhaps in a sealed class, since it doesn't get prettier up the chain...) - seeSqlConnection.CreateCommand
(vsDbConnection.CreateCommand
), or (perhaps more notably)IEnumerator<T>.Current
(vsIEnumerator.Current
)看来您已经从示例中找出了
virtual
和override
,因此:'
abstract
' 也可以应用于成员'virtual
',在这种情况下,您无需指定该方法的实现(直接在签名后的“;
”)。 这会强制所有具体后代实现该方法。“
new
”与继承无关,但可以在成员的后代类中使用,以隐藏基类中具有完全相同签名的成员。简而言之 ;)
It appears you have already figured out
virtual
andoverride
from your example, so:'
abstract
' can also be applied on members instead of 'virtual
', in which case you do not specify an implementation for the method (';
' directly after the signature). This forces all concrete descendants to implement the method.'
new
' has nothing to do with inheritance, but can instead be used in a descendant class on a member to hide a member in the base class that has the exact same signature.In a nutshell ;)
进一步到其他答案。
当您希望允许子类执行自己的处理、不进行处理甚至仅调用父类处理函数时,覆盖。 重写或虚函数不必在后代类中实现。
当您不希望在基类中执行任何处理但希望任何继承类实现该方法时,请使用抽象。 (当继承类的行为可能有很大不同时最好)。 如果一个类只包含抽象方法,那么它实际上是一个接口类型。 指定为抽象的函数必须在子类中实现(如果没有,编译器将抛出错误)。
Further to the other answers.
Overrride for when you wish to allow child classes to perform their own processing, no processing or even just call the parent class processing for a function. An override or virtual function does not have to be implemented in descendent classes.
Abstract when you don't wish to perform any processing in your base class but want that method to be implemented by any inheriting class. (Best when the inheriting class behaviour can differ drastically). If a class contains nothing but abstract methods then it is effectively an interface type. A function specified as abstract MUST be implemented in the child class (the compiler will throw an error if not).