【问题标题】:Function overriding without virtual and override没有虚拟和覆盖的函数覆盖
【发布时间】:2014-11-05 06:41:20
【问题描述】:

我只有一个基本问题:

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

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

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

但如果我:

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

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

从各个地方删除虚拟和覆盖关键字,然后代码也可以工作。

这怎么可能?

或者如果代码在没有虚拟和覆盖的情况下可以正常工作,那么覆盖和虚拟(整个函数覆盖)有什么用???

编辑:

我通过它调用上述类的方法

 static void Main(string[] args)
        {



            derivedVirtualTest objderivedVirtualTest = new derivedVirtualTest();
            objderivedVirtualTest.vTest();

            virtualTest objvirtualTest = new virtualTest();
            objvirtualTest.vTest();

            Console.ReadLine();


        }

【问题讨论】:

  • 你说这段代码有效,但你从未展示过你是如何测试它的。也发布该代码。这是最重要的部分。
  • @SriramSakthivel 刚刚发布。请看一下
  • 参考this 要使用多态性,您需要将编译时类型作为基类型而不是派生类型。只需将derivedVirtualTest objderivedVirtualTest 更改为virtualTest objderivedVirtualTest 即可查看差异。

标签: c# asp.net .net


【解决方案1】:

正如 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();
}

将产生:

我是基地

我是派生的

我是基地

另外的区别是,在覆盖的情况下,您可以发展您的基类,例如更改基成员的签名或完全删除它,而无需更改隐藏的成员。在某些情况下,这可能完全适合需求,而在某些情况下可能不太适合。

如果要覆盖,您必须也更改覆盖成员的签名,否则您的代码将无法编译。

【讨论】:

  • 假设在上面的例子中只有两个类:Base 和 Shadowing 并且 OverrideMe 在 Base 中没有被声明为虚拟的。那这叫阴影吗????
  • 是的。如果通过 Base 类型引用派生类,则永远不会调用派生方法。另外,你甚至可以让隐藏方法返回一些值(不是void),编译器不会产生错误,只警告没有使用new关键字。跨度>
【解决方案2】:

在第二个例子中,也许你可以这样测试你的代码:

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-02-25
    • 1970-01-01
    • 2021-09-30
    • 2015-06-17
    • 2015-12-15
    • 2011-11-23
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多