关于C:虚拟方法和抽象方法的区别


Difference between virtual and abstract methods

本问题已经有最佳答案,请猛点这里访问。

以下是一些来自msdn的代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
// compile with: /target:library
public class D
{
    public virtual void DoWork(int i)
    {
        // Original implementation.
    }
}

public abstract class E : D
{
    public abstract override void DoWork(int i);
}

public class F : E
{
    public override void DoWork(int i)
    {
        // New implementation.
    }
}

有人能就抽象方法和虚拟方法之间的区别解释上述代码吗?


虚拟方法有一个实现,并为派生类提供覆盖它的选项。抽象方法不提供实现并强制派生类重写该方法。

因此,抽象方法中没有实际的代码,子类必须重写该方法。虚拟方法可以有代码,这通常是某个对象的默认实现,任何子类都可以使用override修饰符重写该方法并提供自定义实现。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
public abstract class E
{
    public abstract void AbstractMethod(int i);

    public virtual void VirtualMethod(int i)
    {
        // Default implementation which can be overridden by subclasses.
    }
}

public class D : E
{
    public override void AbstractMethod(int i)
    {
        // You HAVE to override this method
    }
    public override void VirtualMethod(int i)
    {
        // You are allowed to override this method.
    }
}


首先,您应该知道虚拟方法和抽象方法之间的区别。

抽象方法

  • 抽象方法驻留在抽象类中,它没有主体。
  • 抽象方法必须在非抽象子类中重写。

虚拟方法

  • 虚拟方法可以驻留在抽象类和非抽象类中。
  • 不需要重写派生中的虚拟方法,但可以。
  • 虚方法必须有body….可以被"override关键字"重写…..


摘要方法:

  • 如果抽象方法是在类中定义的,那么类应该声明为抽象类。

  • 抽象方法应只包含方法定义,而不应包含包含方法体/实现。

  • 抽象方法必须在派生类中重写。

虚拟方法:

  • 虚拟方法可以在派生类中进行重载,但不能强制性的。
  • 虚拟方法必须同时具有方法体/实现有了定义。

例子:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
public abstract class baseclass
        {
            public abstract decimal getarea(decimal Radius);

            public virtual decimal interestpermonth(decimal amount)

            {
                return amount*12/100;
            }
            public virtual decimal totalamount(decimal Amount,decimal principleAmount)
            {
                return Amount + principleAmount;
            }
        }

        public class derivedclass:baseclass
        {
            public override decimal getarea(decimal Radius)
            {
                return 2 * (22 / 7) * Radius;
            }
            public override decimal interestpermonth(decimal amount)
            {
                return amount * 14 / 100;
            }

        }

抽象方法必须在派生类中调用override,否则将导致编译时错误在虚拟环境中,你可以或者不可以覆盖它,这取决于它是否足够好,使用它。

例子:

1
2
3
4
5
6
7
8
9
10
11
12
abstract class twodshape
{
    public abstract void area(); // no body in base class
}

class twodshape2 : twodshape
{
    public virtual double area()
    {
        Console.WriteLine("AREA() may be or may not be override");
    }
}