【问题标题】:What are some real-world examples of abstract new/virtual/override/abstract keywords?抽象新/虚拟/覆盖/抽象关键字的一些真实示例是什么?
【发布时间】:2009-06-24 06:30:39
【问题描述】:

我正在从 PHP 迁移到 C#。

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

然而,在 C# 中,我只花了大约 20 分钟尝试了关键字 newvirtualabstractabstract 的各种组合baseinheriting 类中的 strong>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.";
        }
    }

}

【问题讨论】:

标签: c# abstract-class


【解决方案1】:

virtual/override是核心多态对;听起来你已经破解了这些

abstract 类似于virtual,但是没有没有合理的基础实现;用例:可能是Stream,实际实现对字节进行处理是必要的。这会强制类为abstract

new 通常应该避免;它破坏了多态性......最常见的情况是使用更具体的签名/返回类型重新公开(可能在密封类中,因为它不会在链上更漂亮......) - 请参阅SqlConnection.CreateCommand (对比DbConnection.CreateCommand),或者(也许更值得注意)IEnumerator&lt;T&gt;.Current(对比IEnumerator.Current

【讨论】:

    【解决方案2】:

    看来您已经从您的示例中找出了virtualoverride,所以:

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

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

    简而言之;)

    【讨论】:

      【解决方案3】:

      进一步了解其他答案。

      当您希望允许子类执行它们自己的处理、不处理或什至只调用父类处理某个函数时覆盖。不必在后代类中实现覆盖或虚函数。

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

      【讨论】:

        猜你喜欢
        • 2014-03-18
        • 1970-01-01
        • 2018-02-22
        • 1970-01-01
        • 2010-12-03
        • 2018-05-23
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多