方法隐藏加上覆盖呼叫决策

时间:2016-05-08 09:06:00

标签: c# method-overriding method-hiding

如果基于类型引用对象的方法覆盖保持方法,则将决定调用。 在基于对象类型的方法隐藏的情况下,将决定调用。

任何人都可以向我解释在覆盖+隐藏时调用决策的方法。

public class Base
    {
        public virtual void DoIt()
        {
        }
    }

    public class Derived : Base
    {
        public  override void DoIt()
        {
        }
    }

    public class Derived1 : Derived
    {
        public new void DoIt()
        {
        }
    }
    class Program
    {
        static void Main(string[] args)
        {

            Base b = new Derived();
            Derived d = new Derived();
      #1    b.DoIt();                      // Calls Derived.DoIt
      #2    d.DoIt();                     // Calls Derived.DoIt
            b = new Derived1();
            d = new Derived1();
      #3    b.DoIt();                      // Calls Derived.DoIt
      #4    d.DoIt();
}
}
由于运行时多态性,

#1和#2调用Derived.DoIt。

#4名为Derived.DoIt,因为d是Dreived类型(方法隐藏)。

但为什么#3称为Derived.DoIt。

在c#中覆盖加隐藏时的调用顺序是什么。

提前致谢

3 个答案:

答案 0 :(得分:1)

因为#3是Base类型的实例。这里,Base的最后一个派生方法驻留在Derived类中,因此它被调用。

new /方法隐藏/阴影与方法覆盖的不同之处在于覆盖意味着您要自定义基本方法,而new意味着您只是为同一方法名称提供不同的实现

答案 1 :(得分:1)

在方法覆盖中,它决定了运行时调用哪种类型的方法,但方法隐藏或阴影是编译时间,编译器在编译时知道哪种类型的方法是当你在方法签名而不是覆盖中使用派生类型中的new关键字时调用,这意味着如果你将使用基类的引用调用它将调用基类实现,如果你使用派生类引用它将调用派生类方法实现。

派生类实现在基类中隐藏。

如果你这样写:

b = new Derived1();
b.DoIt() // (run-time) will call Dervied method implementation as Dervied has overridden 
        // so calling via base reference will call overridden implementation if any
       //otherwise base class implementation will get called

Derived1 d1 = (Derived1)b;
d1.DoIt(); // (compile time) will call Derived1 method implementation due to hiding in Derived1
Derived d = (Derived)b;
d.DoIt(); // (run-time) will call Derived method implementation due to override 

答案 2 :(得分:0)

#3调用Derived.DoIt(),因为该方法只是隐藏的,如果使用适当的强制转换,它仍然是外部可调用的。变量b是Base类型,因此您正在访问Base可用的方法。这是通过Derived覆盖的那个,因此您的结果是Derived.DoIt中的结果。你有一个Derived1类型的变量并在那里调用DoIt,Derived1.DoIt会被调用。

public class Base
{
    public virtual void DoIt()
    {
        Console.WriteLine("Base.DoIt was called!");
    }
}

public class Derived : Base
{
    public override void DoIt()
    {
        Console.WriteLine("Derived.DoIt was called!");
    }
}

public class Derived1 : Derived
{
    public new void DoIt()
    {
        Console.WriteLine("Derived1.DoIt was called!");
    }
}
class Program
{
    static void Main(string[] args)
    {

        Base b = new Derived();
        Derived d = new Derived();
        Console.WriteLine("#1");
        b.DoIt();                      
        Console.WriteLine("#2");
        d.DoIt();                     
        b = new Derived1();
        d = new Derived1();
        Console.WriteLine("#3");
        b.DoIt();                    
        Console.WriteLine("#4");
        d.DoIt();
        Console.WriteLine("#5");
        Derived1 e = new Derived1();
        e.DoIt();
        Console.ReadKey();
    }
}