需要有关objective-c多态性和继承的帮助

时间:2014-05-09 07:33:17

标签: objective-c inheritance polymorphism

ClassA.h

@interface classA

-(void)print1;
-(void)print2;

@end

ClassA.m

-(void)print1 {
    NSLog(@"I am class A 1");
}

-(void)print2 {
    NSLog(@"I am class A 2");
}

ClassB.h

@interface classB : classA

-(void)print1;

@end

ClassB.m

-(void)print1 {
    NSLog(@"I am class B");
}

AppDelegate.m

ClassA *a1 = [[ClassB alloc]init];
    [a1 print1];
    [a1 print2];

输出

I am class B
I am class A 2

错误

ClassB *a1 = [[ClassA alloc]init];

问题

ClassBClassA的孩子,意味着ClassB具有ClassA功能,也有自己的ClassA功能。但是ClassB不知道classA *a1 = [[classB alloc]init];是它的孩子。

那么classB *a1 = [[classA alloc]init];如何工作并给出上述输出 而{{1}}正在给出错误

2 个答案:

答案 0 :(得分:1)

对于classA *a1 = [[classB alloc]init];的情况,因为在Objective-C中,方法在运行时被解析。 [a1 print1]a1对象发送一条消息,该消息可以是运行时的任何内容,以调用方法print1。即使你可以调用[a1 some_random_method]编译器会发出警告而不是错误。因为,在运行时可能会添加some_random_method

对于第二个案例classB *a1 = [[classA alloc]init];,我认为您会收到错误,因为并非所有classA都是classB

classB可能有额外的成员和方法。通过将classA对象类型转换为classB,您将尝试访问那些具有未定义行为的额外成员和方法。因此,编译器不支持从classAclassB的隐式类型转换,并且会出错。

但是,您可以明确地将classA对象强制转换为classB。在运行时,您可以向此对象添加classB特有的方法(objective-C支持在运行时添加方法)并调用它们。

答案 1 :(得分:1)

[[classB alloc]init]
- 这是您实际创建对象的部分,而classA *a1
只是一个声明,简单地说,是什么将是"预期"从这个对象来看。您的classB是classA的子类,因此它具有classA所具有的所有内容,因此在访问属性或使用方法时不会导致错误。
另一方面,当您创建一个classA实例并将其强制转换为classB时:
classB *a1 = [[classA alloc]init]
编译器希望这个对象能够执行classB能够做的事情,并且因为classB是classA扩展,所以它可能会导致错误。