2014-05-09 45 views
0

ClassA.h需要更多关于Objective-C的多态性和继承

@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孩子意味着ClassBClassA功能和自身也。但ClassA不知道ClassB是它的孩子。

那么如何classA *a1 = [[classB alloc]init];工作,并给予上述输出 和classB *a1 = [[classA alloc]init];是给错误

+0

这实际上对大多数(也许是所有)OOP语言都有效。 – Sulthan

回答

1

[[classB alloc]init]
- 这就是你实际创建的对象,而
classA *a1
只是一个宣言,把它简单的部分,会是什么“预期”从这个对象是。您的classB是classA的一个子类,因此它具有classA所拥有的全部内容,因此在访问属性或使用方法时不会导致错误。
在另一方面,当你创建一个ClassA的实例,并将其转换为CLASSB:
classB *a1 = [[classA alloc]init]
编译器会想到这个对象做什么CLASSB是能够做到的,而且由于CLASSB是ClassA的扩展,则可能会导致错误。

0

对于classA *a1 = [[classB alloc]init];的情况下在Objective-C的工作,因为,方法是在运行时解析。 [a1 print1]发送消息给a1对象,该对象可以在运行时调用方法print1。即使你可以调用[a1 some_random_method]编译器会发出警告,但不会出错。因为在运行时可能会添加some_random_method

对于第二种情况classB *a1 = [[classA alloc]init];,我想你会得到这个错误,因为这个概念并不全是classAclassB

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

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

+0

感谢您的回复,但我没有得到您的第二点。 –

+0

如果有意义,请参阅编辑。 – doptimusprime