没有虚拟和覆盖的功能覆盖

本文关键字:覆盖 功能 虚拟 | 更新日期: 2023-09-27 18:29:14

我只有一个基本问题:

public class virtualTest
   {
       public virtual void vTest()
       {
           Console.WriteLine("Base Class");
       }
   }
   public class derivedVirtualTest : virtualTest
   {
       public override void  vTest()
        {
            Console.WriteLine("Derived Class");
        }
   }

在这里,我使用了函数vTest()的函数覆盖

但是如果i:

public class virtualTest
   {
       public void vTest()
       {
           Console.WriteLine("Base Class");
       }
   }
   public class derivedVirtualTest : virtualTest
   {
       public void  vTest()
        {
            Console.WriteLine("Derived Class");
        }
   }

从各个位置删除virtual和override关键字,然后代码也可以工作。

这怎么可能呢?

或者,如果代码在没有虚拟和重写的情况下运行良好,那么重写和虚拟(整个函数重写)的用途是什么???

EDIt:

我调用上述类的方法

 static void Main(string[] args)
        {

            derivedVirtualTest objderivedVirtualTest = new derivedVirtualTest();
            objderivedVirtualTest.vTest();
            virtualTest objvirtualTest = new virtualTest();
            objvirtualTest.vTest();
            Console.ReadLine();

        }

没有虚拟和覆盖的功能覆盖

正如qwr所解释的,OOP的主要区别在于多态性。这意味着,如果您通过基类型引用访问覆盖基成员的类,则对可覆盖成员执行的调用将重定向到覆盖。

如果类隐藏/隐藏了基本成员,则不会重定向调用,并且正在执行基类的方法。

因此,给定:

class Base
{
    public virtual void OverrideMe()
    {
        Console.WriteLine("I'm the base");
    }
}
class Derived : Base
{
    public override void OverrideMe()
    {
        Console.WriteLine("I'm derived");
    }
}
class Shadowing : Base
{
    public void OverrideMe()
    {
        Console.WriteLine("I'm shadowing");
    }
}

并以这种方式使用它们:

var instances = new Base[] {new Base(), new Derived(), new Shadowing()};
foreach (var instance in instances)
{
    instance.OverrideMe();
}

将产生:

我是基地

我是衍生

我是基地

另外的区别是,在重写的情况下,您可以进化基类,比如更改基成员的签名或完全删除它,而不更改隐藏的签名。在某些情况下,这可能完全适合需求,而在某些情况中,则不太适合。

在重写的情况下,还必须更改重写成员的签名,否则您的代码将无法编译。

在第二个例子中,您可能会这样测试代码:

derivedVirtualTest deviTest = new derivedVirtualTest();
deviTest.vTest();  //Result "Derived Class"

试试这个,你会发现这个功能还没有被覆盖:

virtualTest deviTest = new derivedVirtualTest();
deviTest.vTest();  //Result "Base Class"
//This will result "Dervived class" in the first one

当您的密封方法覆盖方法时,将需要它

public class Animal{  
    public virtual void eat() { Console.WriteLine("eating..."); }  
    public virtual void run() { Console.WriteLine("running..."); }  
  
}  
public class Dog: Animal  
{  
    public override void eat() { Console.WriteLine("eating bread..."); }  
    public sealed override void run() {   //If you skipped override here it will throws an error
    Console.WriteLine("running very fast...");   
    }  
}  
public class TestSealed  
{  
    public static void Main()  
    {  
        BabyDog d = new BabyDog();  
        d.eat();  
        d.run();  
    }  
}