8

对于这个继承问题,我似乎找不到令人满意的答案。为什么有时要声明这样的子类型:

Shape myCircle = new Circle();

而这其他时间?

Circle myShape = new Circle();

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

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

4

3 回答 3

7

通常希望以多态方式处理具体类的对象,以避免在可以避免它们的地方创建对特定类型的依赖关系。例如,如果您创建 aCircle的目的是绘制它,并且Draw()是 a 的方法Shape,那么最好将其声明myCircle为形状,以防您稍后决定将其替换为正方形。

另一方面,如果您打算对 做一些特定的事情Circle,例如设置它的半径,那么您需要声明myCircleCircle,因为SetRadius()在 上可能不可用Shape

于 2012-06-08T15:48:30.073 回答
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;
}
于 2012-06-08T15:48:01.020 回答
1

除了@dasblinkenlight 的答案之外,您还可以使用第一个声明,而不是第二个声明,因为您希望将myCircleobject的行为限制为Circle的成员。

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

你不能做相反的事情:

Circle myCircle = new Shape();

原因在这里描述。

否则,如果您使用第二个声明,myCircle将是一个Circle对象,使用Circle.

于 2012-06-08T16:16:53.507 回答