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

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© LeeWong 中级黑马   /  2014-10-20 21:16  /  1321 人查看  /  8 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

本帖最后由 LeeWong 于 2014-10-20 21:31 编辑
  1. /*
  2. 测试
  3. Animal *a = [Dog new];
  4. [a eat];
  5. 究竟是调用父类animal的方法还是dog子类的方法,调用一个父类不存在,而子类新加的方法时从哪里调用
  6. 结果:
  7. 无论是run方法还是eat方法都是调用的cat中的
  8. 老师讲的说:对于a 本质上是一个cat类型的  但是编译器认为他是一个 animal类型的
  9. !!!!!!!
  10. 我的问题是:在执行 run和eat方法时 编译器应该是先去animal中查找有无此方法(编译链接中的警告证明),那么对于animal中存在的eat方法、不存在的run方法  这其中的调用是一个怎么样的过程呢? 父类中有的为什么要去子类调用?父类中没有的有怎么去父类中调用(步骤)?

  11. */

  12. #import <Foundation/Foundation.h>

  13. @interface Animal : NSObject
  14. {
  15.     int age;//年龄
  16. }

  17. //吃东西
  18. - (void)eat;

  19. @end

  20. @implementation Animal

  21. - (void)eat
  22. {
  23.     NSLog(@"animal 正在吃东西");
  24. }

  25. @end

  26. @interface Cat : Animal

  27. - (void)eat;
  28. - (void)run;
  29. @end

  30. @implementation Cat

  31. - (void)eat
  32. {
  33.     NSLog(@"cat 正在吃东西");
  34. }

  35. - (void)run
  36. {
  37.     NSLog(@"cat 跑了几步");
  38. }
  39. @end

  40. int  main()
  41. {
  42.     Animal *a = [Cat new];
  43.     [a run];
  44.     [a eat];
  45.    
  46. }
复制代码

评分

参与人数 1技术分 +1 收起 理由
星河鹭起 + 1

查看全部评分

8 个回复

正序浏览
coyote 中级黑马 2014-10-21 13:22:53
9#
LeeWong 发表于 2014-10-21 10:08
编译链接的时候  认为是animal类型的!这是编译器的思想
执行时 是按照dog类型的执行 这是这个对象的本质 ...

是的 建议以后不要这样写
回复 使用道具 举报
LeeWong 中级黑马 2014-10-21 10:08:39
8#
coyote 发表于 2014-10-20 23:48
多态的局限性:父类类型的指针变量不能直接调用子类特有的方法。编译的时候编译器认为a变量是animal类型 ...

编译链接的时候  认为是animal类型的!这是编译器的思想
执行时 是按照dog类型的执行 这是这个对象的本质

是这样理解吗
回复 使用道具 举报
coyote 中级黑马 2014-10-20 23:48:00
7#
LeeWong 发表于 2014-10-20 22:35
那如果都是去等号后面的子类中去查找方法,为啥编译连接时会警告,run类没有定义呢! ...

多态的局限性:父类类型的指针变量不能直接调用子类特有的方法。编译的时候编译器认为a变量是animal类型的,所以先去animal里找对应方法,所以会警告,但是运行的时候还是会调Dog的方法,不建议这样做,如果这样写可以通过Dog *d = (Dog *)a;将a变量强制转换成Dog类型的就可以了
回复 使用道具 举报
coyote 发表于 2014-10-20 22:20
其实创建的对象是什么类型 主要看你等号后面是什么类  你等号后面是Dog 所以创建出来的对象就是Dog类型的   ...

那如果都是去等号后面的子类中去查找方法,为啥编译连接时会警告,run类没有定义呢!
回复 使用道具 举报
其实创建的对象是什么类型 主要看你等号后面是什么类  你等号后面是Dog 所以创建出来的对象就是Dog类型的  也会优先调用Dog类的方法 如果Dog类里没有才会去找父类中的方法  这是我的理解
回复 使用道具 举报
魔法少年十三 发表于 2014-10-20 21:37
本质就是父类类型调用子类方法

父类如何调用子类呢,子类继承父类,就有了父类的方法。 父类是如何调用子类的呢,能不能详细的说一下!
回复 使用道具 举报
本质就是父类类型调用子类方法
回复 使用道具 举报
额 怎么回事 发了好几次怎么都 显示不全啊
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马