C#中的纯虚方法是什么?

50

有人告诉我要把我的类设为抽象类:

public abstract class Airplane_Abstract

让一个名为move的方法成为虚方法

 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
}

2
如果你对纯虚函数和非纯虚函数(优点和缺点)的讨论感兴趣,我会自私地引导你去看我的博客文章。:) - Steven Jeuris
7个回答

96

我的猜测是,告诉你写一个“纯虚方法”的人是C ++程序员而不是C#程序员……但相当的概念是抽象方法:

public abstract void TurnRight();

这会强制具体的子类通过实现 TurnRight 方法来覆盖它。


1
@allthosemiles:对于抽象方法,是的。抽象方法的重点在于它没有主体。 - Jon Skeet
19
纯虚函数是一个通用的名称,不针对特定的编程语言。它表示抽象类中的虚函数,没有实现代码,必须由派生类重写实现。 - Steven Jeuris
6
@Steven:嗯...可能吧,但我之前只在C ++的语境中看到过。我认为任何谈论它们的人可能都有C ++的背景 :) - Jon Skeet
2
@Steven:是的,我认为那几乎可以肯定是解释。 - Jon Skeet
2
@Jon Skeet:看来你是对的。似乎还存在一些不一致的命名,尽管我找到了一篇试图概括一些术语的科学文章。哦,也许有人应该编辑维基百科。 :) - Steven Jeuris
显示剩余4条评论

13

"Pure virtual" 是 C++ 的术语。在C#中,它的等效术语是抽象方法。


11

他们可能意思是这些方法应该标记为abstract

 public abstract void TurnRight();

然后您需要在子类中实现它们,而不是使用一个空的虚拟方法,在这种情况下,子类将不必覆盖它。


8

纯虚函数是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...
   }
}

然而,您必须实现和的所有函数声明,并进行分配,否则将出现编译器错误。如果您想要可选的虚拟实现,您需要使用抽象类来进行虚拟方法和接口来进行纯虚拟方法。
实际上,接口函数和抽象函数之间存在差异,即接口仅声明了函数,所有接口函数都必须是public,因此没有像private或protected这样的花哨的类属性,所以非常快,而抽象函数是实际的类方法,没有实现,并且强制在派生类中实现,因此您可以使用抽象函数放置private、protected并访问成员变量,并且大多数时候它会更慢,因为类继承关系在运行时被分析(也称为vtable)。

2

在Airplane_Abstract类中,您没有实现任何功能,但是强制消费者“继承者”实现它们。

只有继承并实现抽象函数后,Airplane_Abstract类才能使用。


-2

这不是一个答案,因为它描述的是虚方法而不是纯虚方法。纯虚方法没有实现,因此必须被重写而不是可以被重写。 - R. Schreurs

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接