【问题标题】:Difference between virtual and abstract methods [duplicate]虚拟方法和抽象方法之间的区别[重复]
【发布时间】:2013-01-21 15:11:29
【问题描述】:

这是来自MSDN的一些代码:

// 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.
    }
}

谁能解释一下上面代码中抽象方法和虚方法的区别?

【问题讨论】:

标签: c# oop virtual-functions abstract-function


【解决方案1】:

抽象方法:

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

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

  • 必须在派生类中覆盖抽象方法。

虚拟方法:

  • 虚拟方法可以在派生类中被覆盖,但不能 强制性的。
  • 虚拟方法必须有方法体/实现 与定义。

示例:

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;
            }
        }

【讨论】:

    【解决方案2】:

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

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

    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.
        }
    }
    

    【讨论】:

    • 非常棒!但是有一个问题......您是否必须为子类中的抽象方法明确声明override [因为它需要被覆盖]?
    • 对于抽象方法,您必须明确说明它,是的。对于虚拟方法,它更复杂。如果您没有在此处声明override 关键字,则原始方法将被隐藏。如果这是您的意图,您可以使用 new 关键字来消除警告,但您想要隐藏方法的情况很少见。因此,除非您特别想使用方法隐藏,否则应始终使用 override 关键字
    • 我们如何在 E 类之外调用 E 类 VirtualMethod?
    • @Jaydeep Shil 你不能,也不应该。如果 D 覆盖了虚方法,则意味着应该从外部使用该代码。
    • 如果 E VirtualMethod() 有实现,这意味着它有一个用法 else 可以被声明为抽象。
    【解决方案3】:

    必须在派生类中调用抽象方法,否则会产生编译时错误 在虚拟中,您可能会或可能不会覆盖它,这取决于它是否足够好使用它

    例子:

    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");
        }
    }
    

    【讨论】:

      【解决方案4】:

      首先你应该知道虚方法和抽象方法的区别。

      抽象方法

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

      虚拟方法

      • 虚拟方法可以驻留在抽象类和非抽象类中。
      • 不必重写派生的虚方法,但可以。
      • 虚拟方法必须有主体......可以被“覆盖关键字”覆盖......

      【讨论】:

      • 必须在非抽象子类中重写抽象方法。不是这样的,你也可以在抽象类中重写它。
      猜你喜欢
      • 2014-10-05
      • 2021-10-18
      • 2011-01-28
      • 1970-01-01
      • 2010-10-30
      • 2014-03-18
      • 2011-07-18
      • 2018-09-26
      • 1970-01-01
      相关资源
      最近更新 更多