多态和转换我想了解c#中的多态,所以通过尝试一些构造,我想出了以下案例:classShape{publicvirtualvoidDraw(){Console.WriteLine("Shape.Draw()");}}classCircle:Shape{publicoverridevoidDraw(){Console.WriteLine("Circle.Draw()");我知道为了将draw()消息发送给几个相关对象,以便它们可以根据它们的实现来操作,我必须更改(在这种情况下)形状“指向”的实例:Shapeshape=newCircle();形状.绘制();//好的;这打印:Circle.Draw()但是为什么,当我这样做时:Circlecircle=newCircle();圆.画();//好的;这打印:Circle.Draw()Shapeshape=circleasShape;//或Shapeshape=(Shape)circle;形状.绘制();它打印:“Circle.Draw()”为什么在转换后调用Circle.Draw()而不是Shape.Draw()?是什么原因?转换不会更改运行时对象类型和每个实例具有的特定虚方法的实现。请注意,您的样本在以下两种情况下是相同的:Shapeshape=newCircle();形状.绘制();//好的;这会打印:Circle.Draw()和:Circlecircle=newCircle();形状shape=圆作为Shape;形状.绘制();第一个基本上是第二个的简化版本。正如其他人所提到的,转换对象不会改变实际实例;取而代之的是,强制转换允许变量假定实例特征的一个子集,从对象层次结构的较高位置开始。为了说明为什么需要以这种方式工作,请考虑以下示例://一些缓冲区,其中包含我们将在屏幕上绘制的所有形状ListshapesOnScreen=newList();shapesOnScreen.Add(newSquare());shapesOnScreen.Add(newCircle());//绘制所有形状foreach(ShapeshapeinshapesOnScreen){shape.Draw();在foreach循环中调用Draw()将调用派生实例的Draw()方法,即Square.Draw()和Circle.Draw()。在此示例中,这允许您绘制每个单独的形状而无需确切知道在运行时绘制了哪个形状。你只知道你需要一个形状并让形状处理它的绘制方式。如果不是这种情况(这适用于其他语言的继承,而不仅仅是C#),您将无法使用除Shape.Draw()之外的任何东西。您正在覆盖继承类中的方法,因此无论您是否引用不太具体的基类,它总是被调用的版本。如果要调用Shape的版本,则需要Shape类型的实例,而不仅仅是对该类型的引用。其他答案绝对正确,但请尝试更深入一点:多态性是通过使用一种称为虚函数指针表(vTable)的东西实现的。本质上,你会得到类似这样的东西:作为类型继承树一部分的函数。由于Circle继承自Shape,并且您有一个Circle对象(如前所述,转换不影响基础类型),因此您调用Circle.Draw。显然,这是对实际情况的过度简化,但希望它有助于解释为什么多态行为会以这种方式运行。我用is-a解释一下,因为shape是一个圆:Shapeshape=circleasShape;代码完美地解释了自己,你把圆当成一个形状,形状一点也没有改变,它仍然是一个圆,虽然它也是一个形状。您甚至可以检查它是否为圆形:if(shapeisCircle)Console.WriteLine("TheshapeisaCircle!");这是一个圆圈,对吧?所以调用Circle.Draw()应该是完全合乎逻辑的。以上就是《C#学习教程:多态与Foundry分享》的全部内容。如果对你有用,需要进一步了解C#学习教程,希望大家多多关注。本文收集自网络,不代表立场。如涉及侵权,请点击右边联系管理员删除。如需转载请注明出处:
