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? 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.
What's the point of calling super() if it's done automatically? the Ellipse C'tor executed the code in the Shape C'tor.
Why does x1.Draw() which is casted to Shape is executing the code of Ellipse's Draw()? as you can see both x1,x2 printed the same message.
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
When you write
new Circle()
, it creates an instance ofCircle
, so it calls the constructor ofCircle
. The cast is done afterwards. Actually, in this case the cast is redundant, because aCircle
already is aShape
. You're just assigning the instance ofCircle
to a variable of typeShape
; this way the compiler doesn't know the actual concrete type of the variable. TheCircle
instance is not actually converted to anything else.I assume you mean
base()
rather thansuper()
; 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.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 theShape.Draw
method, it is theEllipse
implementation that is executed for an instance ofEllipse
.Note that in the
Circle
class, you didn't use theoverride
keyword on theDraw
method; this means thatCircle.Draw
does not overrideShape.Draw
, it's just an unrelated method that just happens to have the same name. It will not participate in polymorphism, it will only be called if you call it through a variable of typeCircle
.