标签:src instance person 返回值 set ret 学习总结 动物 bsp
父类的指针指向子类的对象
@interface Animal: NSObject
- (void)eat;
@end
@implation Dog : Animal
- (void)eat{
// 实现父类里面的方法
NSLog (@"啃骨头");
}
- (void)shoumen{
NSLog (@"守门");
}
@end
Animal *animal = [[Dog alloc] init];
[animal eat]; // NSLog (@"啃骨头");
// 父类要想调用子类的方法必须强制转换
Dog *dog = (Dog *)animl;
[dog shoumen]; // NSLog (@"守门");
// 多态的应用场景
@implation Person: NSObject
// 传入对应的 动物 比如 传入狗对象就会调用 狗 啃骨头 传入 猫对象就会调用猫 吃鱼的eat方法 因为是继承自Aimal 并且还实现了eat方法 所以 会 执行
- (void)foodAnimal:(Animal *)animal{
[animal eat]; // (所有继承Animal的类都会实现eat的方法即 人饲养动物 )
}
@end
2. id 动态数据类型
id 相当于 NSObject * 是一个万能指针
NSObject *object = [Person new] ; // 多态
但是NSObject是一个静态 数据类型 所以 不能调用 子类的方法 但是 id 可以 调用子类的方法 同时也可以调用子类的私有方法 (只有实现没有声明就是私有方法)
id 和 NSObject 的区别:
a. NSObject 是一个 静态数据类型 ;
b. id是一个动态数据类型;
c. 通过静态数据类型定义变量,不能调用子类的方法,但是 通过动态的数据类型定义变量,是可以调用子类的方法
弊端:
因为id动态类型可以调用任何方法,同时也包括不属于自己的方法 而编译器再编译时又不会报错,所以此时会导致运行时报错。(在一个 子类 Person中没有 eat 这个方法 在另一个子类 Student 有这个方法,此时 id = [Person new]; 用 [id eat] 编译器并不会报错,但是 eat这个方法属于 Student 随意调用了不属于自己(此时的id代表Person)的方法,随意在运行时会报错) 。
应用场景: 多态: 可以减少代码量,避免调用子类特有的方法需要强制转换为子类。
注: id 虽好,但不能滥用。
NSString *str = [[Person alloc] init]; // 把一个对象 错给了一个 类 的对象 在alloc init 时的 init的方法里面如果 是 id 会造成运行时错误 所以有了 instancetype 在错给对象的情况下会给我们一个警告。
NSInteger lenth = [str length]; // 点语法的实质 就是发送一个消息 为我们自动检测是setter还是getter方法
注 : 【Person alloc】 alloc 分配存储空间 返回地址 为所有的属性初始化 [Person init ] init同样的作用 两个返回相同的地址 所以 放在一起写比较规范 用指针变量接受返回的地址 并且可以根据这个地址找到对应的存储空间对立面的所有属性(成员变量、实例变量)进行更改。
标签:src instance person 返回值 set ret 学习总结 动物 bsp
原文地址:http://www.cnblogs.com/gui-zi/p/6185247.html