将派生类转换为基类

Posted

技术标签:

【中文标题】将派生类转换为基类【英文标题】: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。 【参考方案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; // 总是好的。

【讨论】:

以上是关于将派生类转换为基类的主要内容,如果未能解决你的问题,请参考以下文章

将派生类转换为基类

将指针从派生类转换为基类的最佳方法

无法将参数 1 从派生指针转换为基类指针引用

Part7 继承与派生 7.3基类与派生类类型转换

如何将此“命令处理程序映射”从派生类重构为基类?

C ++:将void *转换为基类指针时访问冲突