【问题标题】:Casting Deriving Class as Base Class将派生类转换为基类
【发布时间】:2017-01-08 01:26:10
【问题描述】:

假设我有这个:

使用系统; 公开课程序 { 公共静态无效 Main() { BaseClass bc = new DerivedClass(); bc.Method1(); bc.Method2(); Console.WriteLine(bc.GetType().FullName); // 输出 // 派生 - 方法 1(覆盖) // 基础 - 方法 2 // 派生类 } } 公共类 BaseClass { 公共虚拟无效方法1() { Console.WriteLine("Base - Method1"); } 公共虚拟无效方法2() { Console.WriteLine("Base - Method2"); } } 公共类 DerivedClass : BaseClass { 公共覆盖无效方法1() { Console.WriteLine("Derived - Method1 (override)"); } 公共新无效方法2() { Console.WriteLine("Derived - Method2 (new)"); } }

如果派生类的实例变量 cast 到基类并且该实例变量用于调用被覆盖的方法,则使用 override 关键字覆盖的方法将在派生类中执行实现,而用 new 关键字覆盖的将在基类中执行。

上面示例中的变量bc是如何转换为基类的?

我知道new关键字会覆盖派生类中的方法实现,并且会在派生类的实例变量用于调用被覆盖的方法时执行,但我不知道不知道它是什么类型的转换.. 似乎不是隐式或显式的,可能是类型转换,但我对语法感到困惑。

感谢任何解释。

【问题讨论】:

  • 您似乎并不完全了解virtual 的工作原理。阅读this

标签: c# inheritance casting


【解决方案1】:

我知道new关键字会覆盖派生类中的方法实现

没有。它不会覆盖基类的方法。它声明了一个 new 独立的方法,它只是名称相同并且具有相同的签名。效果是隐藏基类中声明的同签名方法,实际上使基类中声明的同签名方法的调用复杂化。

在您的示例中,没有任何“类型转换”。将类型转换视为提供实例的特定视图——将类合同的特定部分暴露给用户。仅此而已,仅此而已。

例子:

// instance of DerivedClass exposing its full contract via the 'dc' variable
DerivedClass dc = new DerivedClass();

// the same instance of DerivedClass exposing its contract limited to what's declared in BaseClass
BaseClass bc = dc;

// calling Method2 as newly declared in DerivedClass
dc.Method2();

// calling Method2 as declared in BaseClass—the following two lines are equivalent
bc.Method2();
((BaseClass)dc).Method2();

【讨论】:

  • 刚刚编辑了我的帖子,以澄清我在那一行的意思
【解决方案2】:

实际上,没有转换。只有你看待物体的方式。

  • 如果你用基类眼镜看它,你会看到所有基类方法,其中包括派生类中重写的 Method1,但不会包括派生类中的新 Method2,所以你只会从基类中看到 Method2。
  • 如果您使用派生类眼镜查看它,您将看到所有基类方法,其中包括派生类中重写的 Method1,但它现在包括新的Method2 来自派生类。来自基类的原始虚拟 Method1 将不可见。

【讨论】:

    【解决方案3】:

    上例中的变量 bc 是如何转换为基类的?

    这是一个隐式转换,当您将新的 DerivedClass 实例分配给 BaseClass 类型的变量时执行:

    BaseClass bc = new DerivedClass();
    

    【讨论】:

      【解决方案4】:

      啊,我刚刚找到this,我说它似乎不是隐式转换是错误的……我一定是读多了。

      对于引用类型,始终存在从类到其直接或间接基类或接口的任何一个的隐式转换。不需要特殊语法,因为派生类总是包含基类的所有成员。

      派生 d = new Derived(); 基数 b = d; // 总是好的。

      【讨论】:

        猜你喜欢
        • 2013-11-17
        • 2021-02-18
        • 2017-07-18
        • 2011-02-04
        • 2012-09-15
        • 2011-06-30
        相关资源
        最近更新 更多