首页 > 解决方案 > 为什么最后两行输出它们是什么?

问题描述

有人可以帮我理解吗

  1. 这句话是否正确: BaseClass bcdc = new DerivedClass();这意味着 bcdc 是 BaseClass 类的类型,它的值是 DerivedClass 对象的类型?另外,这是什么意思,为什么要像这样实例化一个对象,而不是让类类型与被实例化的新对象相同,例如DerivedClass dc = new DerivedClass()
  2. 为什么bcdc.Method1() => Derived-Method1。是不是因为使用了关键字override,才这么覆盖了virtual Method1?
  3. 为什么bcdc.Method2() => Base-Method2。我很困惑,因为 DerivedClass 中的新关键字应该隐藏 Base-Method2?我认为这是 new 关键字的功能。
class BaseClass  
{  
    public virtual void Method1()  
    {  
        Console.WriteLine("Base - Method1");  
    } 
    public void Method2()  
{  
    Console.WriteLine("Base - Method2");  
} 
}  
  
class DerivedClass : BaseClass  
{  
    public override void Method1()  
{  
    Console.WriteLine("Derived - Method1");  
}  
    public new void Method2()  
    {  
        Console.WriteLine("Derived - Method2");  
    }  
}
class Program  
{  
    static void Main(string[] args)  
    {  
        BaseClass bc = new BaseClass();  //bc is of type BaseClass, and its value is of type BaseClass
        DerivedClass dc = new DerivedClass();  //dc is of type DerivedClass, and its value is of type DerivedClass
        BaseClass bcdc = new DerivedClass();  //bcdc is of type BaseClass, and its value is of type DerivedClass.
                     
        bc.Method1();  //Base - Method1 
        bc.Method2();  //Base - Method2
        dc.Method1();  //Derived - Method1
        dc.Method2();  //Derived - Method2 
        bcdc.Method1(); //Derived - Method1. ??
        bcdc.Method2(); //Base - Method2.  ??
    }   
} ```

标签: c#inheritancepolymorphism

解决方案


这意味着 bcdc 是 BaseClass 类的类型,它的值是 DerivedClass 对象的类型?

是的。但是,我更愿意将其称为带有引用的DerivedClass 对象BaseClass

另外,这意味着什么以及为什么要像这样实例化一个对象,而不是像在 DerivedClass dc = new DerivedClass() 中那样让类类型与被实例化的新对象相同?

一种情况是当您想要调用显式接口方法时。但是,如果您调用方法,会发生非常相似且更常见的情况:MyMethod(BaseClass bcdc).

在这个简单的程序中,所有类型在编译时都很容易知道。但对于较大的程序,情况并非如此,一个方法接受一个BaseClass参数,可以有一堆不同的实现,并且在编译代码时可能不知道所有的实现。

为什么 bcdc.Method1() => Derived-Method1。是不是因为使用了关键字override,才这么覆盖了virtual Method1?

是的,对于标记为虚拟的方法,编译器将插入一个检查,根据实际对象类型将方法调用转发给被覆盖的方法,即DerivedClass。这有时称为虚拟调度动态调度。即该方法将在运行时根据对象类型动态选择。

为什么 bcdc.Method2() => Base-Method2。我很困惑,因为 DerivedClass 中的新关键字应该隐藏 Base-Method2?我认为这是 new 关键字的功能。

Method2 不是虚拟的,所以不会有动态调度。所以引用类型,即BaseClass,将用于确定被调用的方法。这称为静态分派,即调用的方法可以在编译时静态确定。


推荐阅读