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

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

适合有java基础的同学迅速了解OC,个人喜好用代码来记笔记,看起来直观形象;
  1. #import <Foundation/Foundation.h>
  2. typedef enum{
  3.         SexMal='m',SexFem='f'
  4. } Sex;

  5. @interface Score :NSObject
  6. {
  7.         @public
  8.         double mathScore,engScore,cScore;
  9. }
  10. @end
  11. @implementation Score
  12. @end

  13. @interface Person :NSObject
  14. {
  15.         //成员变量非public,而是提供get set方法访问,体现封装特性
  16.         int _age;//命名规范,一般成员变量名以_开头
  17.         double _weight;
  18.         char* _name;
  19.         Sex _sex;
  20. }
  21. - (void)setAge:(int)age;//get set方法的规范写法
  22. - (int)age;
  23. - (void)setWeight:(double)weight;
  24. - (double)weight;
  25. - (void)setName:(char*)name;
  26. - (char*)name;
  27. - (void)setSex:(Sex)sex;
  28. - (Sex)sex;


  29. - (void)eat;
  30. - (void)exercise;
  31. + (void) testSuper;
  32. + (void) testSuper2;
  33. @end

  34. @implementation Person
  35. - (void)setAge:(int)age{_age=age;}
  36. - (int)age{return _age;}
  37. - (void)setWeight:(double)weight{_weight=weight;}
  38. - (double)weight{return _weight;}
  39. - (void)setName:(char*)name{_name=name;}
  40. - (char*)name{return _name;}
  41. - (void)setSex:(Sex)sex{_sex=sex;}
  42. - (Sex)sex{return _sex;}

  43. - (void)eat
  44. {_weight++;}
  45. - (void) exercise
  46. {_weight--;}

  47. + (void) testSuper
  48. {//%@为输出OC对象
  49.         NSLog(@"Person super=%d,self=%d,super class=%@,self class=%@",super,self,[super class],[self class]);
  50.         [self testSuper2];
  51. }
  52. + (void)testSuper2
  53. {
  54.         NSLog(@"Person testSuper2");
  55. }
  56. @end  


  57. @interface Student :Person
  58. {
  59.         @public
  60.         int _studentNo;
  61.         Score* _score;//利用组合来降低耦合性
  62. }
  63. @end;
  64. @implementation Student
  65. - (void)eat
  66. {
  67.         [super eat];
  68.         NSLog(@"Student eat...weight=%.2f",[self weight]);
  69. }
  70. - (void)exercise
  71. {
  72.         [super exercise];
  73.         NSLog(@"Student exercise...weight=%.2f",[self weight]);
  74. }
  75. + (void) testSuper//方法重写(override)
  76. {
  77.         NSLog(@"Student super=%d,self=%d,super class=%@,self class=%@",super,self,[super class],[self class]);
  78.         //利用super调用Person类中的方法与利用Person直接调用并非完全一样
  79.         //用Person调用后,Person中testSuper方法中self指向Person类对象
  80.         //而利用super调用后,Person中testSuper方法中self指向Student类对象       
  81.         [super testSuper];
  82.         [Person testSuper];
  83. }
  84. + (void)testSuper2
  85. {
  86.         NSLog(@"Student testSuper2");
  87. }
  88. @end;


  89. @interface PrimaryStudent:Student
  90. @end
  91. @implementation PrimaryStudent
  92. + (void)testSuper2
  93. {
  94.         NSLog(@"PrimaryStudent testSuper2");
  95. }
  96. @end


  97. @interface Staff:Person
  98. {
  99.         @public
  100.         int _staffNo;
  101. }

  102. @end
  103. @implementation Staff
  104. - (void)eat
  105. {
  106.         [super eat];
  107.         NSLog(@"Staff eat...weight=%.2f",[self weight]);
  108. }
  109. - (void)exercise
  110. {
  111.         [super exercise];
  112.         NSLog(@"Staff exercise...weight=%.2f",[self weight]);
  113. }
  114. @end


  115. //利用OC多态特性,Person*可接收任意其子类对象
  116. void eatSomething(Person* p)
  117. {
  118.         [p eat];
  119. }
  120. void doExercise(Person *p)
  121. {
  122.         [p exercise];
  123. }

  124. int main(int argc, const char * argv[])  
  125. {        
  126.     Student * p=[Student new];[p setWeight:50];
  127.      Person * p2=[Staff new];[p2 setWeight:60];
  128.     eatSomething(p);
  129.     doExercise(p2);

  130.   
  131.    
  132.    
  133.     //测试super
  134.      [Person testSuper];
  135.      [Student testSuper];
  136.          [PrimaryStudent testSuper];
  137.    
  138.      return 0;  
  139. }


  140. /*
  141. OC面向对象语法:
  142. 1>封装:
  143.         成员变量命名以_开始,非public,提供get set方法,
  144.         例 {int _age;}    -setAge:(int)age;   -(int)age;
  145. 2>继承:
  146.         NSObject与NSProxy为OC中两大root class,大部分类都继承NSObject,
  147.         NSObject类中声明了一个Class类型的指针变量isa,该指针指向该对象对应的类对象;
  148.         每个类对象中都有一个superClass指针变量,指向其父类的类对象,
  149.         该指针变量声明在Class类中,所有类加载进内存后都是一个类对象,类对象是Class类的实例;
  150.         子类继承父类,则拥有父类所有成员变量及方法,包括类方法与对象方法;
  151.         子类成员变量名不允许与父类重名(java成员变量可重名),但是方法名可以重复(重写);
  152.         OC调用方法时,会从子类到父类的层级顺序查找(通过类对象中的superClass指针变量查找父类方法);
  153.         父类声明的方法可以子类中实现;
  154.        
  155.         继承缺点:
  156.         类与类之间关系太紧密导致代码耦合性太强;
  157.                   有些场合可利用组合降低耦合性
  158.                                 *继承表示子类是父类
  159.                                 *组合表示A类拥有B类
  160.                                
  161.         super关键字:
  162.         (super本质上与 self不同,self是类的隐藏的参数变量,指向当前调用方法的对象(类也是对象,类对象),
  163.         另一个隐藏参数是_cmd,代表当前类方法的selector,
  164.     而super并不是隐藏的参数,它只是一个"编译器指示符")
  165.         调用方法时,使用[super methodName]可以调用父类的方法,对象方法则调用父类
  166.         对象方法,类方法中则调用父类的类方法,无法调用成员变量(java中super可以调用父类成员变量)
  167.    
  168.         OC普通方法调用通过消息机制发送,调用
  169.         id objc_msgSend(id theReceiver, SEL theSelector, ...)方法,
  170.         receiver为调用该方法的对象或类对象指针,与self一样,SEL为方法选择器,...为动态方法参数,
  171.         该方法实现伪代码大致为
  172.         id objc_msgSend(id theReceiver, SEL theSelector, ...)
  173.         {
  174.                 if theReceiver 是Class对象
  175.                 {
  176.                         根据theSelector在theReceiver中从当前类到父类顺序查找类方法;
  177.                        
  178.                 }else if theReceiver是对象
  179.                 {
  180.                         根据theSelector在theReceiver->isa中从当前类到父类顺序查找对象方法;
  181.                        
  182.                 }
  183.                 找到后调用该方法,将theReceiver传给隐藏形参self
  184.                 return theReceiver;
  185.         }
  186.        
  187.         而当编译器遇到通过[super XXX]方式调用的方法则调用
  188.         id objc_msgSendSuper(struct objc_super *super, SEL op, ...)方法,
  189.         super的结构为 struct objc_super {
  190.                             id receiver;
  191.                            Class superClass;
  192.                         };
  193.         这里superClass即类对象中的superClass指针变量,
  194.         receiver为当前方法中的self ,类方法指向类对象,对象方法则指向对象;
  195.         该方法实现的伪代码大致是
  196.         id objc_msgSendSuper(struct objc_super *super, SEL op, ...)
  197.         {
  198.                 通过SEL在super->superClass中查找到需要调用的方法的selector,
  199.                 然后调用上面那个消息发送的方法
  200.                 注:selector为方法的选择器,子类重写父类方法,他们的selector是不一样的;
  201.                 return objc_msgSendSuper(super->receiver, selector, ...);
  202.                
  203.         }
  204.         因此在每个有用到super的方法中,都会生成一个struct objc_super,
  205.         通过[super XXX]调用的方法中的self等于生成super的方法中的self;

  206. 多态:
  207.         父类指针可以接收任意子类对象实例
  208.         使用场景:函数参数设置为父类指针,可接收任意子类对象
  209. */
复制代码

2 个回复

倒序浏览
有几个疑问就是,老师说的OC中子类成员变量不允许与父类中的重名,而我这里测试重名没问题,不加public的成员变量也可以直接访问,
不过应该是我用window写的
,编译器不完善还是什么原因吧;
有发生同样问题的么?
回复 使用道具 举报
好牛逼的样子!
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马