[英]Inheritance and Polymorphism in C#
There's a simple question, What will the program print to the console? 有一个简单的问题, 程序将在控制台上打印什么?
I never thought that I could be wrong as much as I was with this piece of code. 我从来没有想过我会像这段代码一样犯错。 It behaved the other way around of what my logic expected from it. 它的行为与我的逻辑期望相反。
If someone could please enlighten the reason for each line printed I would be really appreciate that. 如果有人能启发每行打印的原因,我将非常感激。
And also, what is the meaning of instantiating a new Circle and casting it to a Shape? 而且,实例化一个新的Circle并将其转换为Shape的含义是什么? why is it treated also as an Ellipse? 为什么也将其视为椭圆形?
Thank you so much 非常感谢
EDIT: I was asked to specify what was I expecting the output to be. 编辑:我被要求指定我期望输出是什么。 So: 所以:
creating a Circle and casting it to a Shape, I was thinking that only the Shape C'tor will be executed, as it's a Shape. 创建一个Circle并将其投射到Shape上,我当时认为只有Shape C'tor会被执行,因为它是Shape。
What's the point of calling super() if it's done automatically? 如果自动完成,调用super()有什么意义? the Ellipse C'tor executed the code in the Shape C'tor. 椭圆C'tor执行Shape C'tor中的代码。
Why does x1.Draw() which is casted to Shape is executing the code of Ellipse's Draw()? 为什么强制转换为Shape的x1.Draw()执行Ellipse的Draw()代码? as you can see both x1,x2 printed the same message. 如您所见,x1,x2都打印了相同的消息。
Hope I was more clear, thank you. 希望我更加清楚,谢谢。
namespace ConsoleApplication2
{
class Shape
{
public Shape()
{
Console.WriteLine("SHAPE CTOR");
}
public virtual void Draw()
{
Console.WriteLine("Shape.Draw()");
}
}
class Ellipse : Shape
{
public Ellipse()
{
Console.WriteLine("ELLIPSE CTOR");
}
public sealed override void Draw()
{
Console.WriteLine("ELLIPSE.Draw()");
}
}
class Circle : Ellipse
{
public static void Main()
{
Shape x1 = (Shape)new Circle();
Ellipse x2 = (Ellipse)new Circle();
Circle x3 = new Circle();
x1.Draw();
x2.Draw();
x3.Draw();
}
public void Draw()
{
Console.WriteLine("CIRCLE DRAW");
}
}
}
Output: 输出:
SHAPE CTOR
ELLIPSE CTOR
SHAPE CTOR
ELLIPSE CTOR
SHAPE CTOR
ELLIPSE CTOR
ELLIPSE.Draw()
ELLIPSE.Draw()
CIRCLE DRAW
creating a Circle and casting it to a Shape, I was thinking that only the Shape C'tor will be executed, as it's a Shape. 创建一个Circle并将其投射到Shape上,我当时认为只有Shape C'tor会被执行,因为它是Shape。
When you write new Circle()
, it creates an instance of Circle
, so it calls the constructor of Circle
. 当您编写new Circle()
,它将创建Circle
的实例,因此将调用Circle
的构造函数。 The cast is done afterwards. 投射是在此之后完成的。 Actually, in this case the cast is redundant, because a Circle
already is a Shape
. 实际上,在这种情况下,投射是多余的,因为Circle
已经是 Shape
。 You're just assigning the instance of Circle
to a variable of type Shape
; 您只是将Circle
实例分配给Shape
类型的变量; this way the compiler doesn't know the actual concrete type of the variable. 这样,编译器就不知道变量的实际具体类型。 The Circle
instance is not actually converted to anything else. Circle
实例实际上并未转换为其他任何实例。
What's the point of calling super() if it's done automatically? 如果自动完成,调用super()有什么意义? the Ellipse C'tor executed the code in the Shape C'tor. 椭圆C'tor执行Shape C'tor中的代码。
I assume you mean base()
rather than super()
; 我假设你的意思是base()
而不是super()
; but anyway, you're not calling it, the compiler does it for you automatically. 但是无论如何,您不是在调用它,而是由编译器自动为您完成。 The constructor of a derived class must always call a constructor of the base class to initialize the state of the base class. 派生类的构造函数必须始终调用基类的构造函数来初始化基类的状态。 In the case of the default constructor, you don't need to do it explicitly because the compiler does it for you. 在默认构造函数的情况下,您不需要显式地执行此操作,因为编译器会为您执行此操作。
Why does x1.Draw() which is casted to Shape is executing the code of Ellipse's Draw()? 为什么强制转换为Shape的x1.Draw()执行Ellipse的Draw()代码? as you can see both x1,x2 printed the same message. 如您所见,x1,x2都打印了相同的消息。
That's the whole point of polymorphism. 这就是多态的全部要点。 At runtime, the method that is executed depends on the actual concrete type of the object. 在运行时,执行的方法取决于对象的实际具体类型。 Since Ellipse
overrides the Shape.Draw
method, it is the Ellipse
implementation that is executed for an instance of Ellipse
. 由于Ellipse
覆盖Shape.Draw
方法,它是Ellipse
是对于的一个实例中执行实现Ellipse
。
Note that in the Circle
class, you didn't use the override
keyword on the Draw
method; 注意,在Circle
类中,您没有在Draw
方法上使用override
关键字。 this means that Circle.Draw
does not override Shape.Draw
, it's just an unrelated method that just happens to have the same name. 这意味着Circle.Draw
不会覆盖Shape.Draw
,它只是恰好有相同的名称无关的方法。 It will not participate in polymorphism, it will only be called if you call it through a variable of type Circle
. 它不会参与多态,只有通过Circle
类型的变量调用它时,它才会被调用。
new
). 即使对象被强制转换,它仍将调用最后一个类型的方法(除非您通过new
中断继承)。 creating a Circle and casting it to a Shape, I was thinking that only the Shape C'tor will be executed, as it's a Shape. 创建一个Circle并将其投射到Shape上,我当时认为只有Shape C'tor会被执行,因为它是Shape。
As you are saying: You are creating a Circle
and casting it to a Shape
. 正如您所说的:您正在创建一个Circle
并将其转换为Shape
。 The constructor will only be called when you are creating an instance of an object. 仅在创建对象实例时才调用构造函数。 Therefor you are simply calling the constructor of Circle
. 因此,您只需调用Circle
的构造函数即可。 The process of casting is not calling any constructors. 转换过程不调用任何构造函数。
You always need to call the base constructor with : base()
. 您始终需要使用以下命令调用基本构造函数: base()
。 When there is a parameter less base constructor the compiler will add the : base()
for you (Because its clear). 如果没有基本构造函数的参数,编译器将为您添加: base()
(因为其清除)。 You can use base()
to call a specific base constructor which might not be the parameterless one. 您可以使用base()
来调用特定的基本构造函数,该构造函数可能不是无参数的。
The Draw()
method you have there in your Circle
class is only known by the compiler when you have a Circle
instance. 仅当您具有Circle
实例时,编译器才知道您在Circle
类中具有的Draw()
方法。 In you case you have got a Ellipse
and a Shape
which don't know about the custom Draw
method and are therefor calling the overridden Draw
method from Ellipse
在您的情况下,您有一个不知道自定义Draw
方法的Ellipse
和Shape
,因此可以从Ellipse
调用重写的Draw
方法
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.