适合有java基础的同学迅速了解OC,个人喜好用代码来记笔记,看起来直观形象;
- #import <Foundation/Foundation.h>
- typedef enum{
- SexMal='m',SexFem='f'
- } Sex;
- @interface Score :NSObject
- {
- @public
- double mathScore,engScore,cScore;
- }
- @end
- @implementation Score
- @end
- @interface Person :NSObject
- {
- //成员变量非public,而是提供get set方法访问,体现封装特性
- int _age;//命名规范,一般成员变量名以_开头
- double _weight;
- char* _name;
- Sex _sex;
- }
- - (void)setAge:(int)age;//get set方法的规范写法
- - (int)age;
- - (void)setWeight:(double)weight;
- - (double)weight;
- - (void)setName:(char*)name;
- - (char*)name;
- - (void)setSex:(Sex)sex;
- - (Sex)sex;
- - (void)eat;
- - (void)exercise;
- + (void) testSuper;
- + (void) testSuper2;
- @end
- @implementation Person
- - (void)setAge:(int)age{_age=age;}
- - (int)age{return _age;}
- - (void)setWeight:(double)weight{_weight=weight;}
- - (double)weight{return _weight;}
- - (void)setName:(char*)name{_name=name;}
- - (char*)name{return _name;}
- - (void)setSex:(Sex)sex{_sex=sex;}
- - (Sex)sex{return _sex;}
- - (void)eat
- {_weight++;}
- - (void) exercise
- {_weight--;}
- + (void) testSuper
- {//%@为输出OC对象
- NSLog(@"Person super=%d,self=%d,super class=%@,self class=%@",super,self,[super class],[self class]);
- [self testSuper2];
- }
- + (void)testSuper2
- {
- NSLog(@"Person testSuper2");
- }
- @end
-
- @interface Student :Person
- {
- @public
- int _studentNo;
- Score* _score;//利用组合来降低耦合性
- }
- @end;
- @implementation Student
- - (void)eat
- {
- [super eat];
- NSLog(@"Student eat...weight=%.2f",[self weight]);
- }
- - (void)exercise
- {
- [super exercise];
- NSLog(@"Student exercise...weight=%.2f",[self weight]);
- }
- + (void) testSuper//方法重写(override)
- {
- NSLog(@"Student super=%d,self=%d,super class=%@,self class=%@",super,self,[super class],[self class]);
- //利用super调用Person类中的方法与利用Person直接调用并非完全一样
- //用Person调用后,Person中testSuper方法中self指向Person类对象
- //而利用super调用后,Person中testSuper方法中self指向Student类对象
- [super testSuper];
- [Person testSuper];
- }
- + (void)testSuper2
- {
- NSLog(@"Student testSuper2");
- }
- @end;
- @interface PrimaryStudent:Student
- @end
- @implementation PrimaryStudent
- + (void)testSuper2
- {
- NSLog(@"PrimaryStudent testSuper2");
- }
- @end
- @interface Staff:Person
- {
- @public
- int _staffNo;
- }
- @end
- @implementation Staff
- - (void)eat
- {
- [super eat];
- NSLog(@"Staff eat...weight=%.2f",[self weight]);
- }
- - (void)exercise
- {
- [super exercise];
- NSLog(@"Staff exercise...weight=%.2f",[self weight]);
- }
- @end
- //利用OC多态特性,Person*可接收任意其子类对象
- void eatSomething(Person* p)
- {
- [p eat];
- }
- void doExercise(Person *p)
- {
- [p exercise];
- }
- int main(int argc, const char * argv[])
- {
- Student * p=[Student new];[p setWeight:50];
- Person * p2=[Staff new];[p2 setWeight:60];
- eatSomething(p);
- doExercise(p2);
-
-
-
-
- //测试super
- [Person testSuper];
- [Student testSuper];
- [PrimaryStudent testSuper];
-
- return 0;
- }
- /*
- OC面向对象语法:
- 1>封装:
- 成员变量命名以_开始,非public,提供get set方法,
- 例 {int _age;} -setAge:(int)age; -(int)age;
- 2>继承:
- NSObject与NSProxy为OC中两大root class,大部分类都继承NSObject,
- NSObject类中声明了一个Class类型的指针变量isa,该指针指向该对象对应的类对象;
- 每个类对象中都有一个superClass指针变量,指向其父类的类对象,
- 该指针变量声明在Class类中,所有类加载进内存后都是一个类对象,类对象是Class类的实例;
- 子类继承父类,则拥有父类所有成员变量及方法,包括类方法与对象方法;
- 子类成员变量名不允许与父类重名(java成员变量可重名),但是方法名可以重复(重写);
- OC调用方法时,会从子类到父类的层级顺序查找(通过类对象中的superClass指针变量查找父类方法);
- 父类声明的方法可以子类中实现;
-
- 继承缺点:
- 类与类之间关系太紧密导致代码耦合性太强;
- 有些场合可利用组合降低耦合性
- *继承表示子类是父类
- *组合表示A类拥有B类
-
- super关键字:
- (super本质上与 self不同,self是类的隐藏的参数变量,指向当前调用方法的对象(类也是对象,类对象),
- 另一个隐藏参数是_cmd,代表当前类方法的selector,
- 而super并不是隐藏的参数,它只是一个"编译器指示符")
- 调用方法时,使用[super methodName]可以调用父类的方法,对象方法则调用父类
- 对象方法,类方法中则调用父类的类方法,无法调用成员变量(java中super可以调用父类成员变量)
-
- OC普通方法调用通过消息机制发送,调用
- id objc_msgSend(id theReceiver, SEL theSelector, ...)方法,
- receiver为调用该方法的对象或类对象指针,与self一样,SEL为方法选择器,...为动态方法参数,
- 该方法实现伪代码大致为
- id objc_msgSend(id theReceiver, SEL theSelector, ...)
- {
- if theReceiver 是Class对象
- {
- 根据theSelector在theReceiver中从当前类到父类顺序查找类方法;
-
- }else if theReceiver是对象
- {
- 根据theSelector在theReceiver->isa中从当前类到父类顺序查找对象方法;
-
- }
- 找到后调用该方法,将theReceiver传给隐藏形参self
- return theReceiver;
- }
-
- 而当编译器遇到通过[super XXX]方式调用的方法则调用
- id objc_msgSendSuper(struct objc_super *super, SEL op, ...)方法,
- super的结构为 struct objc_super {
- id receiver;
- Class superClass;
- };
- 这里superClass即类对象中的superClass指针变量,
- receiver为当前方法中的self ,类方法指向类对象,对象方法则指向对象;
- 该方法实现的伪代码大致是
- id objc_msgSendSuper(struct objc_super *super, SEL op, ...)
- {
- 通过SEL在super->superClass中查找到需要调用的方法的selector,
- 然后调用上面那个消息发送的方法
- 注:selector为方法的选择器,子类重写父类方法,他们的selector是不一样的;
- return objc_msgSendSuper(super->receiver, selector, ...);
-
- }
- 因此在每个有用到super的方法中,都会生成一个struct objc_super,
- 通过[super XXX]调用的方法中的self等于生成super的方法中的self;
- 多态:
- 父类指针可以接收任意子类对象实例
- 使用场景:函数参数设置为父类指针,可接收任意子类对象
- */
复制代码 |
|