将子类实例分配给超类实例

时间:2011-08-11 15:31:56

标签: objective-c ios

这听起来很抽象。 假设我们有以下实例:

Shape *aShape
Rectangle *aRect // Rectangle is a subclass or Shape

aRect = [[Rectangle alloc] init];
// and some other code to set properties of aRect

aShape = aRect

从Obj-C的角度来看,最后一行分配是允许的并且是有效的。 但是,在Shape类中,并未定义Rectanlge的所有属性 - 毕竟,Rectangle是Shape的子类。

这个赋值是否会使某些aRect的属性和值无效?

2 个答案:

答案 0 :(得分:4)

不,它不会使aRect的任何属性或值无效。现实生活中的一个例子 - 仅仅因为你把某人视为人,不会让他们成为男人或女人;你只是不要用自己的性别来吸引自己。在同一思路中,仅仅因为你将它视为Shape并不会使它变得不那么Rectangle,你的代码只处理它的“形状”方面,忽略任何“矩形”无论如何。

当然,Shape类可能会定义一些可能会将Rectangle实例的内部状态更改为不一致状态的方法。但即使您通过向aRect发送消息来调用相同的方法,这也是一个问题。如果Rectangle类重写此类方法以确保其状态一致,则通过aShape发送该消息仍将调用Rectangle定义的正确行为。

答案 1 :(得分:2)

这只是polymorphism并且不会使他们不再“可访问”的任何属性失效。当然,通过反思或Objective-C消息传递,您仍然可以访问这些值,但会发出警告,除非您将aShape转换为Rectangle

//This will work if it is a rectangle but will generate a warning
[aShape someRectangleMethod];

//This will work without a warning
[(Rectangle*)aShape someRectangleMethod];