黑马程序员技术交流社区

标题: 每日小结:多态 [打印本页]

作者: 崔石炫    时间: 2014-9-25 03:04
标题: 每日小结:多态
多态是面向对象的三大特性之一,与继承联系紧密,多态特性依赖于继承,没有继承,多态无从说起。
多态特性的体现:父类指针指向子类对象。
好处:处理父类、子类共同的行为时,可以用父类指针作为参数,传入子类对象。不需要为子类对象声明实现专用方法。如果传入的是子类对象,则会调用子类中的方法
局限性:
一种行为只在子类中存在时,无法用父类指针作为方法参数,即父类指针无法直接调用子类特有的方法,虽然编译不会报错(OC语言,指针与对象在运行时动态绑定,编译器容错能力强,很多时候只是告警,并不报错),但是不建议这么写。必须使用父类指针调用子类特有的方法时,使用强制类型转换来实现。
参考以下代码:
  1. #import <Foundation/Foundation.h>

  2. @interface Person : NSObject
  3. {
  4.         @public
  5.         int _age;
  6.         double _weight;
  7. }
  8. - (void)walk;
  9. @end

  10. @implementation Person
  11. - (void)walk
  12. {
  13.         NSLog(@”年龄为:%d岁,体重为:%f kg的人执行动作:走路” , _age , _weight);
  14. }
  15. @end

  16. @interface Student : Person
  17. - (void)walk;
  18. - (void)takeExam;
  19. @end

  20. @implementation Student
  21. - (void)walk
  22. {
  23.         NSLog(@”年龄为:%d岁,体重为:%f kg的学生执行动作:走路” , _age , _weight);
  24. }

  25. - (void)takeExam
  26. {
  27.         NSLog(@”年龄为:%d岁,体重为:%f kg的学生执行动作:考试” , _age , _weight);
  28. }
  29. @end

  30. void test(Person *p)
  31. {
  32.         [p , wakl];
  33. }

  34. void test2(Student *stu)
  35. {
  36.         [stu takeExam];
  37. }

  38. int main()
  39. {
  40.         Person *p = [Person new];
  41.         Student *stu = [Student new];

  42.         p->_age = 21;
  43.         p->weight = 61.2;

  44.         stu->_age = 19;
  45.         stu->weight = 54.2;

  46.         test(p); // 打印:年龄为21岁,体重为61.2kg人执行动作:走路
  47.         test(stu); // 打印:年龄为19岁,体重为54.2kg的学生执行动作:走路

  48.         test2(stu); // 打印:年龄为19岁,体重为54.2kg的学生执行动作:考试
  49.         test2(p); // 错误的写法,takeExam是子类Student特有的方法,不能传入父类指针

  50.         return 0;
  51. }
复制代码

解析:
test方法使用参数为Person类指针,传入Student类指针stu时,stu类中也有walk方法,此方法覆盖父类Person中的walk方法,调用成功。此处应用了面向对象的多态特性,来处理父类Person和子类Student都有的方法walk
test2方法使用参数为Student类指针,内部调用Student类对象的takeExam方法,此方法并不存在于父类Person中,所以在处理子类特有的方法takeExam时不能传入父类指针。





欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2