封装、继承、多态
- end
1.封装
1)set/get方法
#import <Foundation/Foundation.h>
@interface Persion : NSObject
{
//@public - 对象实例可直接访问的
//面向对象:内部结构不应暴露
//成员变量应尽量使用set/get方法操作
int age;
}
- (void) setAge:(int)i; //set方法,修改age
- (int) getAge; //get方法,获取age。OC中的get方法名就是属性名
@end
@implementation Persion
//set方法:无返回值;方法名为 set变量名;有一个和变量同类型的参数
- (void) setAge:(int)i{
//这里应当进行逻辑,确保数据有效性
age = i;
}
//get方法:有一个和变量同类型的返回值;方法名同变量名(Java方式 get变量名);无参数
- (int) getAge{
return age;
}
@end
int main(){
Persion *p = [Persion new];
//避免类内部结构的暴露,利于数据的安全性
[p setAge:30];
NSLog(@"年龄:%d", [p getAge]);
return 0;
}
2)类方法
#import <Foundation/Foundation.h>
@interface Persion : NSObject
//被大括号包裹的是成员变量,只能被对象实例访问
{
int age;
}
//用+修饰。类方法,静态方法。只能使用类名调用
+ (void)show;
- (void)show;
- (void)show2;
@end
@implementation Persion
+ (void)show{
//age = 20; //成员变量不能被类方法访问
NSLog(@"+Persion");
//[Persion show]; //死循环
}
- (void)show{
NSLog(@"-Persion");
[Persion show]; //对象方法调用类方法
}
- (void)show2{
/**
self是个指针。指向调用当前show2方法的对象实例
(当前是动态方法,如果是静态方法,则指向类)
**/
[self show]; //对象方法的相互调用
}
@end
int main(){
//[Persion show]; //消息接收者为类,这个show是静态方法-类方法
[[Persion new] show2]; //消息接收者是对象,这个show是动态方法-对象方法
return 0;
}
2.继承
1)方法重写
#import <Foundation/Foundation.h>
/** ----------------父类-------------------- **/
@interface Persion : NSObject
{
int age;//成员变量
}
+ (void)show; //静态方法-类方法
+ (void)show2;
- (void)show; //动态方法-对象方法
- (void)show2;
@end
@implementation Persion
+ (void)show{
NSLog(@"Persion父类静态方法");
}
+ (void)show2{
NSLog(@"父类Persion的静态方法2");
}
- (void)show{
NSLog(@"Persion父类动态方法");
}
- (void)show2{
NSLog(@"父类Persion动态方法2");
}
@end
/** ----------------子类-------------------- **/
@interface Chinese : Persion //-------------子类1
{
//不允许有和父类同名的成员变量
NSString *food;
}
+ (void)show; //和父类重名的方法,发生重写
- (void)show; //和父类重名的方法,发生重写
@end
@implementation Chinese
+ (void)show{
NSLog(@"Chinese子类自己的静态方法");
}
- (void)show{
NSLog(@"子类Chinese自己的动态方法");
}
@end
/**
不声明,直接定义一个只有方法没有属性的类
但这里的English会继承Persion的属性
**/
@implementation English : Persion //-------------子类2
/**
这个静态方法不能和父类中发生重名。否则[self show]不能验证调用的是父类的show
+ (void)show{ 如果这里是show,表示自己的静态方法show
[self show]; 这一行调用自己的静态show,发生死循环
运行报错:Segmentation fault:11
}
**/
+ (void)show3{
[self show]; //self表示自身类。这里的show为静态方法。自身没有,调用父类的
}
- (void)english{
[self show]; //self表示自身对象。先找本类中有没有show动态方法,有则调用,无则在父类查找
}
- (void) setAge:(int)i{
age = i; //这个age继承自父类
}
- (int) getAge{
return age; //冥冥中有这么一个age ... ...
}
@end
/** ----------------main-------------------- **/
int main(){
[Chinese show]; //调用子类自己的静态方法
[Chinese show2]; //子类自己没有,就使用父类的静态方法
[[Chinese new] show]; //调用子类实例自己的动态方法
[[Chinese new] show2]; //子类自身方法中没有show2,就从父类中找
[English show3]; //编译报警,运行正常
English *e = [English new];
[e show]; //English实例没有show这个动态方法,直接使用Persion父类的动态方法
[e english]; //English实例有english动态方法
[e setAge:34]; //编译报警,运行正常
NSLog(@"EnglishAge:%d", [e getAge]); //编译报警,运行正常
return 0;
}
2)super
#import <Foundation/Foundation.h>
/** ----------------父类-------------------- **/
@implementation Persion : NSObject
+ (void)show{
NSLog(@"Persion父类静态方法");
}
- (void)show{
NSLog(@"父类Persion动态方法");
}
@end
/** ----------------子类-------------------- **/
@implementation English : Persion
+ (void)show{
[super show]; //调用父类的静态show方法
}
- (void)show{
[English show]; //调用自己的静态show方法
}
- (void)english{
[super show]; //调用父类的动态show方法
[self show]; //调用自己的动态show方法
}
@end
/** ----------------main-------------------- **/
int main(){
[[English new] english];
return 0;
}
3.多态
#import <Foundation/Foundation.h>
/** ----------------父类-------------------- **/
@interface Persion : NSObject
- (void)show;
@end
@implementation Persion
- (void)show{
NSLog(@"父类Persion动态方法");
}
@end
/** ----------------子类-------------------- **/
@interface English : Persion
@end
@implementation English
- (void)show{
NSLog(@"English子类动态方法");
}
@end
/** ----------------main-------------------- **/
int main(){
/**多态是由继承体现的**/
//以Persion身份出现的English实例
Persion *e = [English new];
//e真实身份是English,执行English的show
[e show];
//以NSObject身份出现的English实例
NSObject *e2 = [English new];
//e2属于NSObject类,但最终身份是English,执行English的show
//不建议的用法
[e2 show]; //报警,因为NSObject中没有show方法。如果是Java会报错
English * e3 = [English new];
//把NSObject身份的e2转为English身份。前提是e2根本就是English
e3 = (English *)e2; //(English *)是为了编译不报警
[e3 show];
//仅编译时报警,因为OC是弱类型语言
NSString *n = [English new];
[n show];//e真实身份是English,执行English的show
return 0;
}
- end