A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

【提问】父类能否访问子类的方法?

1、多态
多态:就是某一类食物的多种形态
【程序中的多态】不同的对象以自己的方式响应相同名称方法的能力称为多态

2、多态的条件
有继承关系,有方法重写,父类的声明变量指向子类对象

3、多态的优点
主要好处是简化了编程接口。它容许在类和类之间重用一些习惯性的命名,而不用为每一个新加的函数命名一个新名字。这样,编程接口就是一些抽象的行为的集合,从而和实现接口的类的区分开来。

多态也使得代码可以分散在不同的对象中而不用试图在一个函数中考虑到所有可能的对象。这样使得代码扩展性和复用性更好一些。当一个新的情景出现时,也无需对现有的代码进行改动,而只需要增加一个新的类和新的同名方法

4、多态的原理
动态绑定:
动态类型能使程序直到执行时才确定对象所属类型
动态类型绑定是程序直到执行时才确定要对对象调用的实际方法
OC不同于传统程序设计语言,他可以在运行时加入新的数据类型和新的程序模块,动态类型识别,动态绑定,动态加载
id类型:通用指针类型,弱类型,编译时不进行类型检查

5、多态注意点:
1)如果存在多态,父类可以访问子类特有的方法
假设子类Dog有一个特有得方法bark。
例如:
  1.                 #import "Animal.h"
  2.                 #pragma mark Dog类定义部分
  3.                 @interface Dog : Animal
  4.                 -(void) bark;
  5.                 @end
  6.                
  7.                 #pragma mark Dog类实现部分
  8.                 @implementation Dog
  9.                 -(void)bark{
  10.                     NSLog(@"Wang wang...");
  11.                 }
  12.                 @end
  13.                
  14.                         Animal *ani2 = [Dog new];
  15.                        // [ani2 bark];//直接调用Dog类独有的bark方法会在编译时报错
  16.         [(Dog*)ani2 bark];//这样做可以
复制代码
打印结果:

2015-10-04 22:21:33.774VariableClass[2198:303] Wang wang...

  1.         2)
  2.                 Animal *ani = [Animal new];
  3.         [(Dog*)ani bark];//这样做是错误的,因为其实ani是Animal的实例而不是Dog的实例。因此根本没有bark这个方法,此时只是暂时让编译器无法检测出来,运行时会报错。
复制代码


6、多态的代码实现
  1. #pragma mark Animal类定义部分
  2. @interface Animal : NSObject
  3. //吃东西
  4. -(void) eat;
  5. //跑
  6. -(void) run;

  7. @end
  8. #pragma mark Animal类实现部分
  9. @implementation Animal

  10. -(void)eat{
  11.     NSLog(@"Animal eat...");
  12. }

  13. -(void)run{
  14.     NSLog(@"Animal run...");
  15. }

  16. @end
  17. #pragma mark Dog类定义部分
  18. @interface Dog : Animal

  19. @end
  20. #pragma mark Dog类实现部分
  21. @implementation Dog
  22. -(void)eat{
  23.     NSLog(@"Dog eat shit...");
  24. }

  25. -(void)run{
  26.     NSLog(@"Dog run...");
  27. }

  28. @end
  29. #pragma mark Cat类定义部分
  30. @interface Cat : Animal

  31. @end
  32. #pragma mark Cat类实现部分
  33. @implementation Cat
  34. -(void)eat{
  35.     NSLog(@"Cat eat fish...");
  36. }

  37. -(void)run{
  38.     NSLog(@"Cat climb the tree...");
  39. }
  40. @end


  41. #import <Foundation/Foundation.h>
  42. #import "Animal.h"
  43. #import "Dog.h"
  44. #import "Cat.h"

  45. int main(int argc, const char * argv[])
  46. {

  47.     @autoreleasepool {
  48.         //未使用多态
  49.          NSLog(@"---------未使用多态------------------");
  50.         Animal *ani = [Animal new];
  51.         [ani eat];
  52.         Dog *dog = [Dog new];
  53.         [dog eat];
  54.         Cat *cat = [Cat new];
  55.         [cat eat];
  56.         //使用多态:父类指针指向子类对象
  57.         NSLog(@"----使用多态:父类指针指向子类对象--------");
  58.         Animal *ani2 = [Dog new];
  59.         [ani2 eat];
  60.         [ani2 run];
  61.         Animal *ani3 = [Cat new];
  62.         [ani3 eat];
  63.         [ani3 run];
  64.         
  65.     }
  66.     return 0;
  67. }
复制代码
打印结果:
2015-10-04 22:10:44.068VariableClass[2089:303] ---------未使用多态------------------
2015-10-04 22:10:44.071 VariableClass[2089:303] Animaleat...
2015-10-04 22:10:44.072 VariableClass[2089:303] Dogeat shit...
2015-10-04 22:10:44.073 VariableClass[2089:303] Cateat fish...
2015-10-04 22:10:44.073VariableClass[2089:303] ----使用多态:父类指针指向子类对象--------
2015-10-04 22:10:44.074 VariableClass[2089:303] Dogeat shit...
2015-10-04 22:10:44.075 VariableClass[2089:303] Dogrun...
2015-10-04 22:10:44.075 VariableClass[2089:303] Cateat fish...

2015-10-04 22:10:44.076 VariableClass[2089:303] Catclimb the tree...

0 个回复

您需要登录后才可以回帖 登录 | 加入黑马