【问题标题】:Pure virtual methods in C#?C# 中的纯虚方法?
【发布时间】:2011-06-24 08:31:07
【问题描述】:

有人告诉我要把我的班级抽象化:

public abstract class Airplane_Abstract

并创建一个名为 move virtual 的方法

 public virtual void Move()
        {
            //use the property to ensure that there is a valid position object
            double radians = PlanePosition.Direction * (Math.PI / 180.0);

            // change the x location by the x vector of the speed
            PlanePosition.X_Coordinate += (int)(PlanePosition.Speed * Math.Cos(radians));

            // change the y location by the y vector of the speed
            PlanePosition.Y_Coordinate += (int)(PlanePosition.Speed * Math.Sin(radians));
        }

另外 4 种方法应该是“纯虚拟方法”。 那究竟是什么?

它们现在看起来都是这样的:

public virtual void TurnRight()
{
    // turn right relative to the airplane
    if (PlanePosition.Direction >= 0 && PlanePosition.Direction < Position.MAX_COMPASS_DIRECTION)
        PlanePosition.Direction += 1;
    else
        PlanePosition.Direction = Position.MIN_COMPASS_DIRECTION;  //due north
}

【问题讨论】:

  • 如果有兴趣,关于纯虚函数和非纯虚函数的讨论(优缺点),我会自私地重定向到我的a blog post。 :)

标签: c# abstract-class pure-virtual


【解决方案1】:

我的猜测是,告诉你编写“纯虚拟”方法的人是 C++ 程序员而不是 C# 程序员……但等价的是抽象方法:

public abstract void TurnRight();

这会强制具体子类使用实际实现覆盖 TurnRight

【讨论】:

  • @allthosemiles:对于抽象方法,是的。抽象方法的关键在于它没有有一个主体。
  • 纯虚拟是general name,而不是特定于语言的
  • @Steven:嗯...可能,但我之前只曾经在 C++ 的上下文中看到过它。我怀疑任何谈论它们的人都可能有 C++ 背景:)
  • @Steven:是的,我认为这几乎可以肯定的解释。
  • @Jon Skeet:看来你是对的。尽管我确实找到了一篇试图概括某些术语的科学文章,但似乎也缺乏一致的命名。哦,也许有人应该编辑维基百科。 :)
【解决方案2】:

“纯虚拟”是 C++ 术语。 C# 等价物是一个抽象方法。

【讨论】:

    【解决方案3】:

    他们可能意味着这些方法应该被标记为abstract

     public abstract void TurnRight();
    

    然后您需要在子类中实现它们,而不是空虚方法,子类不必重写它。

    【讨论】:

      【解决方案4】:

      纯虚函数是 C++ 的术语,但在 C# 中,如果在派生类中实现且该派生类不是抽象类的函数。

      abstract class PureVirtual
      {
          public abstract void PureVirtualMethod();
      }
      
      class Derivered : PureVirtual
      {
          public override void PureVirtualMethod()
          {
              Console.WriteLine("I'm pure virtual function");
          }
      }
      

      【讨论】:

        【解决方案5】:

        或者你甚至可以去界面,认为需要一些小限制:

        public interface IControllable
        {
            void Move(int step);
            void Backward(int step);
        }
        
        public interface ITurnable
        {
           void TurnLeft(float angle);
           void TurnRight(float angle);
        }
        
        public class Airplane : IControllable, ITurnable
        {
           void Move(int step)
           {
               // TODO: Implement code here...
           }
           void Backward(int step)
           {
               // TODO: Implement code here...
           }
           void TurnLeft(float angle)
           {
               // TODO: Implement code here...
           }
           void TurnRight(float angle)
           {
               // TODO: Implement code here...
           }
        }
        

        但是,您必须实现所有 IControllableITurnable 的函数声明已分配,否则会出现编译器错误。如果你想要可选的虚拟实现,你必须去abstract class 为虚拟方法和interface 为纯虚拟方法。

        其实interface函数和abstract函数是有区别的,interface只声明函数,所有interface函数都要公开所以没有花哨类属性,例如privateprotected,所以它非常快,而abstract 函数是没有实现的实际类方法,并且强制在派生类中实现,所以你可以把privateprotected 和用abstract 函数访问成员变量,而且大多数时候它比较慢,因为类继承关系是在运行时分析的。 (又名 vtable)

        【讨论】:

          【解决方案6】:

          然后,您在 Airplane_Abstract 类中没有实现,而是强制该类的消费者“继承者”实现它们。

          在您继承并实现抽象函数之前,Airplane_Abstract 类是不可用的。

          【讨论】:

            【解决方案7】:

            http://en.wikipedia.org/wiki/Virtual_function

            “在面向对象的编程中,虚函数或虚方法是一种函数或方法,其行为可以在继承类中被具有相同签名的函数覆盖。”

            Google 永远是您的朋友。

            【讨论】:

            • 这不是一个答案,因为它描述了一个虚拟的,而不是一个纯虚拟的方法。纯虚方法没有实现,因此必须被覆盖而不是可以被覆盖。
            猜你喜欢
            • 2011-09-08
            • 1970-01-01
            • 2012-10-01
            • 2011-07-10
            • 2014-03-03
            • 2016-06-23
            • 1970-01-01
            • 1970-01-01
            • 2012-04-02
            相关资源
            最近更新 更多