猿问

覆盖vs方法隐藏

覆盖vs方法隐藏

关于覆盖与隐藏C#中的方法有点困惑。每个人的实际用途也将被理解,以及何时使用每个人的解释。


我对重写感到困惑 - 为什么要覆盖?到目前为止我所学到的是,通过覆盖,我们可以在不改变签名的情况下为派生类的方法提供所需的实现。


如果我不覆盖超类的方法并且我对子类中的方法进行了更改,那么是否会更改超类方法?


我也对以下内容感到困惑 - 这表明了什么?


class A

{

    virtual m1()

    {

        console.writeline("Bye to all");

    }

}


class B : A

{

    override m1()

    {

        console.writeLine("Hi to all");

    }

}


class C

{

    A a = new A();

    B b = new B();

    a = b; (what is this)

    a.m1(); // what this will print and why?


    b = a; // what happens here?

}


精慕HU
浏览 373回答 3
3回答

慕侠2389804

覆盖是当override在基类中定义该方法时,在后代类中提供方法的新实现时virtual。隐藏是当你提供了当该方法的新的实现在子类中的方法不是在基类中的定义virtual,或者当你的新的实现并没有指定override。隐藏往往很糟糕; 你应该尽量不要这样做,如果你可以完全避免它。隐藏可能会导致意外事件发生,因为隐藏方法仅在调用您定义的实际类型的变量时使用,而不是在使用基类引用时...另一方面,被覆盖的虚拟方法最终会被即使在子类上使用基类引用调用时,也会调用正确的方法版本。例如,考虑以下类:public class BaseClass{   public virtual void Method1()  //Virtual method   {     Console.WriteLine("Running BaseClass Method1");   }   public void Method2()  //Not a virtual method   {     Console.WriteLine("Running BaseClass Method2");   }}public class InheritedClass : BaseClass{   public override void Method1()  //Overriding the base virtual method.   {     Console.WriteLine("Running InheritedClass Method1");   }   public new void Method2()  //Can't override the base method; must 'new' it.   {     Console.WriteLine("Running InheritedClass Method2");   }}让我们在匹配的引用中使用InheritedClass的实例来调用它:InheritedClass inherited = new InheritedClass();inherited.Method1();inherited.Method2();这会返回你应该期待的东西; 两种方法都表示它们正在运行InheritedClass版本。运行InheritedClass方法1 运行InheritedClass Method2此代码创建相同的实例InheritedClass,但将其存储在BaseClass引用中:BaseClass baseRef = new InheritedClass();baseRef.Method1();baseRef.Method2();通常,根据OOP原则,您应该期望与上面的示例相同的输出。但是你得不到相同的输出:运行InheritedClass方法1 运行BaseClass方法2当您编写InheritedClass代码时,您可能希望所有调用Method2()都运行您在其中编写的代码。通常,这将是它的工作原理 - 假设您正在使用virtual已被覆盖的方法。但是因为您使用的是new/ hidden方法,所以它会调用您正在使用的引用上的版本。如果这是你真正想要的行为,那么; 你去吧 但我强烈建议如果这就是你想要的,那么代码可能存在更大的架构问题。

守着一只汪

方法重写是简单地覆盖派生类中基类方法的默认实现。方法隐藏:您可以在派生类中的虚方法之前使用'new'关键字如class Foo  {     public virtual void foo1()     {     }  }  class Bar:Foo  {     public new virtual void foo1()     {      }  }现在,如果您创建另一个派生自Bar的类Bar1,您可以覆盖在Bar中定义的foo1。
随时随地看视频慕课网APP
我要回答