OC学习笔记02-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 alloc] init];[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;

多态:
	父类指针可以接收任意子类对象实例
	使用场景:函数参数设置为父类指针,可接收任意子类对象
*/

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值