c#将子类声明为类型超类

时间:2012-06-08 15:42:21

标签: c# inheritance

我似乎无法找到这个继承问题的满意答案。为什么有时会声明这样的子类型:

Shape myCircle = new Circle();

还有其他时间?

Circle myShape = new Circle();

Circle是Shape子/子类 .....

在我阅读的OO书籍中似乎没有一致性,并且我可以解释一下我的解释。人们已经向我展示了一个Shapes类的例子,它被实例化为圆形,正方形等......但我不明白你何时使用第一个声明和第二个声明。

3 个答案:

答案 0 :(得分:7)

通常需要处理具体类polymorphically的对象,以避免在可以避免它们的特定类型上创建依赖关系。例如,如果您要创建一个Circle来绘制它,Draw()Shape的方法,那么最好将myCircle声明为形状,以防你决定稍后用方格替换它。

另一方面,如果你打算做Circle特定的事情,比如设置半径,那么你需要将myCircle声明为Circle,因为{{ 1 {}可能无法在SetRadius()上使用。

答案 1 :(得分:4)

也许你有一个形状列表,你并不特别关心它们是什么样的形状,因为你需要对这个列表做什么对所有形状都是通用的(即绘制),你想要将它们添加到像这样的列表

List<Shape> shapeList = new List<Shape>();
shapeList.Add(new Circle());
shapeList.Add(new Rectangle());
foreach (Shape shape in shapeList)
{
    shape.Draw();
}

通过这种方式,您可以访问实际上不同类型但共享公共父对象的对象的常规方法。然后,如果你想做一些特定的圆圈,你可以使用相同的列表。

foreach (Shape shape in shapeList)
{
    if (!(shape is Circle)) continue;
    Circle circle = shape as Circle;
    circle.Radius = 100;
}

答案 2 :(得分:1)

除了@dasblinkenlight的回答之外,您将使用第一个声明而不是第二个声明,因为您希望将myCircle对象的行为限制为Circle的成员。

这是因为CircleShape的子类,这意味着Shape的所有成员都将由Circle继承,并且在某些情况下,因为你正在使用C#(并且覆盖成员并不总是规则,就像在Java中一样),被覆盖。

你不能这样做:

Circle myCircle = new Shape();

原因描述为here

否则,如果您使用的是第二个声明,myCircle将成为Circle对象,使用Circle提供的成员和方法。