抽象 new/virtual/override/abstract 关键字的真实示例有哪些?

发布于 2024-07-23 14:53:07 字数 2346 浏览 5 评论 0 原文

我将从 PHP 迁移到 C#。

在 PHP 中,使用抽象类创建“级联覆盖”模式非常简单明了,基本上“基类方法将处理它,除非继承类具有带有相同的签名”。

然而,在 C# 中,我只花了大约 20 分钟尝试关键字 newvirtualabstractoverride 的各种组合继承类中,直到我最终得到了执行此简单级联覆盖模式的正确组合。

因此,即使下面的代码按照我想要的方式工作,这些添加的关键字也表明 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.";
        }
    }

}

I'm moving from PHP to C#.

In PHP it was simple and straightforward to use abstract classes to create a "cascading override" pattern, basically "the base class method will take care of it unless the inheriting class has a method with the same signature".

In C#, however, I just spent about 20 minutes trying out various combinations of the keywords new, virtual, abstract, and override in the base and inheriting classes until I finally got the right combination which does this simple cascading override pattern.

So even those the code below works the way I want it, these added keywords suggest to me that C# can do much more with abstract classes. I've looked up examples of these keywords and understand basically what they do, but still can't imagine a real scenario in which I would use them other than this simple "cascading override" pattern. What are some real world ways that you implement these keywords in your day-to-day programming?

code that works:

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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

¢好甜 2024-07-30 14:53:08

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 these

abstract is like virtual, but there is no sensible base implementation; use-cases: perhaps a Stream, where it is necessary for the actual implementation to do something with the bytes. This forces the class to be abstract

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...) - see SqlConnection.CreateCommand (vs DbConnection.CreateCommand), or (perhaps more notably) IEnumerator<T>.Current (vs IEnumerator.Current)

云仙小弟 2024-07-30 14:53:08

看来您已经从示例中找出了 virtualoverride,因此:

  • 'abstract' 也可以应用于成员'virtual',在这种情况下,您无需指定该方法的实现(直接在签名后的“;”)。 这会强制所有具体后代实现该方法。

  • new”与继承无关,但可以在成员的后代类中使用,以隐藏基类中具有完全相同签名的成员。

简而言之 ;)

It appears you have already figured out virtual and override 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 ;)

百合的盛世恋 2024-07-30 14:53:08

进一步到其他答案。

当您希望允许子类执行自己的处理、不进行处理甚至仅调用父类处理函数时,覆盖。 重写或虚函数不必在后代类中实现。

当您不希望在基类中执行任何处理但希望任何继承类实现该方法时,请使用抽象。 (当继承类的行为可能有很大不同时最好)。 如果一个类只包含抽象方法,那么它实际上是一个接口类型。 指定为抽象的函数必须在子类中实现(如果没有,编译器将抛出错误)。

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).

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文