我将从 PHP 迁移到 C#。

在 PHP 中,使用抽象类来创建“级联覆盖“模式,基本上”基类方法将处理它,除非继承类有具有相同签名的方法".

然而,在 C# 中,我只花了大约 20 分钟尝试关键字的各种组合 新的, 虚拟的, 抽象的, , 和 覆盖 在里面 根据继承 类,直到我最终得到正确的组合来执行这个简单的级联覆盖模式。

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

}
有帮助吗?

解决方案

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

abstract就像Stream,但 没有合理的基础实现;用例:可能是new,其中必需用于实际实现以对字节执行某些操作。这会强制类SqlConnection.CreateCommand

通常应该避免

DbConnection.CreateCommand;它破坏了多态性......最常见的情况是使用更具体的签名/返回类型重新暴露(可能在密封类中,因为它不会在链条上变得更漂亮......) - 参见 IEnumerator<T>.Current (vs IEnumerator.Current ),或者(或许更值得注意)< a href =“http://msdn.microsoft.com/en-us/library/58e146b7.aspx”rel =“noreferrer”> <=> (vs <=>

其他提示

看来你已经想通了 virtualoverride 从你的例子来看,所以:

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

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

简而言之 ;)

继续其他答案。

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

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

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top