子对象初始化为父对象

时间:2012-03-08 04:43:21

标签: iphone objective-c ios casting

B是A类的子类。

A * a = [[B alloc] init];
B * b = [[A alloc] init];

哪些无效,为什么?

当我输入此内容时,我得到了第二件事的警告,但我无法理解它的含义。它显示“不兼容的指针类型初始化'B * __strong',表达式为'A *'”。也许有人可以告诉我第二个表达式是否有效以及如何做同样的事情。

2 个答案:

答案 0 :(得分:3)

如果BA子类,则可以在任何可以使用A实例的地方使用其实例。反之则不然。

以下是使用Apple课程的真实示例:考虑NSArray及其子类NSMutableArray。由于NSMutableArray NSArray,因此以下分配有效:

NSArray *myArray = [[NSMutableArray alloc] init];

但是,由于NSArray不一定是NSMutableArray,因此以下分配无效:

NSMutableArray *myArray = [[NSArray alloc] init];

编辑从语言的角度来看,两个作业都是有效的:代码将进行编译,如果您避开B的方法,甚至可以运行代码通过A,感谢Objective C的动态方法调度机制。但是编译器不能再验证涉及变量的代码,并告诉您其他潜在的问题。

答案 1 :(得分:0)

A * a = [[B alloc] init];  // OK
B * b = [[A alloc] init];  // INCORRECT

简单地说,第一行是有效的,因为B的任何实例都必须是A的实例。因此,将指向B实例的指针指定给类型A*的变量是很好的。

由于类似的原因,第二行是不正确的:A的实例不一定是B的实例,因此将指向A实例的指针指定给类型为B*的变量并不合适。更具体地说,在第二行中,您直接实例化A,因此生成的对象肯定是而不是 B的实例。

以这种方式思考:将任何方块描述为矩形是正确的,但如果没有矩形为正方形的额外信息则说错了。