2009-06-16 149 views
2

我正在从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."; 
     } 
    } 

} 
+0

下面是关于(罕见)情况的一些说明,其中人们可能想要使用“新”进行方法隐藏。 http://blogs.msdn.com/ericlippert/archive/2008/05/21/method-hiding-apologia.aspx – 2009-06-16 15:20:29

回答

8

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

abstract就像virtual,但有没有合理的基本实现;用例:或许一个Stream,其中它是必要为实际执行某些字节。这迫使班级成为abstract

new通常应该避免;它破坏了多态性......最常见的情况是用更具体的签名/返回类型重新公开(可能是在密封的类中,因为它没有在链上变得更漂亮......) - 参见SqlConnection.CreateCommand(vs DbConnection.CreateCommand),或(也许更值得注意的)IEnumerator<T>.Current(VS IEnumerator.Current

4

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

  • 'abstract' 也可以在会员申请而不是'virtual',在这种情况下,您并未指定该方法的实施(''签字后直接签字'')。这迫使所有具体的后代实施该方法。

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

简而言之)

1

此外到其他的答案。

覆盖您希望允许子类执行自己的处理,不进行处理,甚至只是为某个函数调用父类处理。重写或虚函数不一定要在后代类中实现。

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