将实例视为其超类

时间:2012-09-16 07:48:55

标签: objective-c

我害怕的一点nebbie问题。简而言之,如果我想知道我是否 创建一个对象的子类,我可以使用父类的实例来引用 只有那个对象的父类属性?如果是这样,我可以自由地介于两者之间 子类和父类?

例如,如果我将B定义为A的子类型   - A有方法a   - B有方法b

我可以创建B的实例,然后将其作为对象类型A

引用

排序:     B * b1;     B * b2;     A * a;

b1 = [[B alloc] init];

// Is this allowed?
a = (A *)b1;
b2= (B *)a;

// Are these valid?
[ a a];
[ b2 a];
[ b2 b];

(我在网上看过很多关于一般子类的讨论,但没有 似乎解释了什么时候我可以在一个类和它的超类之间进行转换)

3 个答案:

答案 0 :(得分:1)

一切都在运行时解决;向a发送消息,无论是否将其转换为A*,都会产生相同的结果。

换句话说,演员表没有什么区别;如果你愿意,你可以将它们转移到NSString*,它仍然可以工作。

另一方面,如果对象似乎没有响应发送的消息,则会出现编译时错误。

答案 1 :(得分:0)

我不是100%肯定第一次演员,但我认为两个演员都是合法的。只要原始对象b1的类型为B,第二个强制转换就有意义。否则,向B发送b2消息会导致错误 - 我认为在将消息发送到对象时,会调用一个方法的默认实现,该方法未针对该类型实现。< / p>

另外发送这3条消息也是合法的。方法a对于类A是公开的,因此AB类型的对象会响应消息ab2也会响应b,因为它实际上指的是B类型的对象。

答案 2 :(得分:0)

b1 = [[B alloc] init];
a = (A *)b1;
b2= (B *)a;

总结一下 - 您只有一个对象b1,并且您正在创建两个对象ab2

您想知道是否可以在B上调用类b2的方法,即使它之前是类A的实例?

答案是肯定的,因为所有三个对象都是B类的实例。从一种类型转换为另一种类型是编译器如何解决方法调用的指示。

例如 - 如果你写:

id obj = b1;

后来尝试通过

访问B类的属性
obj.someProperty;

你会得到编译器警告,但如果你施放它:

(B *)obj.someProperty;

您没有收到警告,因为您已向编译器提供了信息。

Objective-C是一个动态的语言。所有三个对象都是类B的实例。将它们转换为其他类并不会改变它们的类。