我很惊讶在C#中看到以下控制台应用程序的输出:
abstract class Shape
{
public abstract void Draw();
}
class Circle : Shape
{
public override void Draw()
{
Console.WriteLine("Drawing Circle");
}
}
class SpecialCircle : Circle
{
public new void Draw()
{
Console.WriteLine("Drawing SpecialCircle");
}
}
class Program
{
static void Main(string[] args)
{
Shape[] myShapes = { new Circle(), new SpecialCircle() };
foreach(Shape s in myShapes)
{
Console.WriteLine(s.GetType());
s.Draw();
}
SpecialCircle scirc = new SpecialCircle();
scirc.Draw();
}
}
有输出:
CallChildClassMethod.Circle
Drawing Circle
CallChildClassMethod.SpecialCircle
Drawing Circle
Drawing SpecialCircle
Press any key to continue . . .
所以我想知道为什么在foreach语句中它识别出数组的第二个元素是SpecialCircle
,但却使用类Draw
中的方法Circle
。与在数组和foreach循环外定义SpecialCircle
对象时的行为相反。
任何人都可以帮我解决这个问题吗?
答案 0 :(得分:4)
这是因为您使用的是new
关键字,如果将其更改为override
,您将获得所期望的行为。
new
不会覆盖基类中的实现,它会隐藏它。这基本上意味着当实例被视为基础时,将调用基本实现,并且当它被视为派生类型时,将调用派生类型实现。
您可以通过
进行测试SpecialCircle scirc = new SpecialCircle();
scirc.Draw();
Circle circle = scirc;
circle.Draw();
这将输出
Drawing SpecialCircle
Drawing Circle
答案 1 :(得分:0)
使用new
时,您必须通过对SpecialCircle
类的引用来调用它。
当您在循环外部调用时,您会引用SpecialCircle
,这会导致调用new
方法。