OC语言--继承、点语法、类别

来源:互联网 发布:自适应滤波的各种算法 编辑:程序博客网 时间:2024/05/17 07:49

1 继承

 

1.0 面向对象的三个基本特征:1.封装2.继承3.多态

 

1.1 生活中的继承

 

-》继承的生活逻辑

a.继承遗产:预先给予,不需要自行再建

b.      人类         父类

男人和女人       子类

乔布斯 和章子怡     对象

 

-》继承的概念:继承(也被称为派生)。

父类拥有的属性和方法,子类直接获得,这个过程叫做继承。

子类在父类基础上,衍生出了自己独有的属性和方法,称为派生。

 

-》父子类的各种称呼:

父类   parentClass    超类 supperClass   基类baseClass

子类   childClass        子类 subClass         派生类derivedClass

1.2 代码中的继承

-》继承的基本语法

a.语法形式

@interface 子类名 : 父类名

@interface Person :NSObject//在oc中任何一个类都必须继承一个类,也就是说,每个必须单继承

@end

 

b.继承之后

子类可以使用父类的所有方法  

子类可以获得父类非私有的成员变量

 

c.类字段和成员方法访问控制

                @interface Person : NSObject//NSObject 根类{@protected//受保护的:,// 子类继承父类之后,// 子类可以直接使用父类的受保护成员变量    int _age;@public//公有的:类内和类外的函数 //都可以直接使用公有的成员变量//这将一定程度上破坏对象信息的隐藏性    int _height;@private//私有的:  类内减方法可以直接使用私有的// 类外的方法不能直接使用,// 但是可以通过实例方法间接访问和使用,// 子类继承父类之后,// 子类可以通过父类的方法间接使用父类私有的变量   int _money;}

 

成员方法:没有@private @protected @public 这样的访问控制

OC中子类继承父类之后就拥有了父类的方法

注:

1、OC中的方法类似于C++中的虚函数

2、OC中是没有类似于C++的private作用域的私有方法,

但是可以通过其他方式实现

 

-》继承在内存中的体现

子类继承父类之后 子类对象的构成:

a.继承的父类的成员变量

b.子类自己特有的成员变量

 

-》重写(Override覆盖)

a.子类从父类继承的方法,有时候不适合子类,子类可以重写这个方法

b.重写就是重新实现一遍父类的方法(方法名一样 实现内容不同)

c.子类重写父类方法之后,子类对象最终执行的是子类重写之后的方法

 

-》多态

a.其实多态就是指,同一个接口不同的实现//重写

b.从OC消息机制看:给不同的对象发送相同的消息,反应不同

 

-》什么时候使用继承  

a.创建大量相似的类

【例】创建象棋中的棋子,车马士象炮。

可以先创建棋子类,作为父类。

 

b.继承一个官方类,添加属性和方法,创建一个更符合当前工程的新类。

 

c.用继承方式统一接口(不常用)

 

-》继承的作用   

代码重复利用,节约资源提高效率

 

-》类簇

a.类簇是基础框架中一种常见的设计模式,基于抽象工厂模式的思想。

它将若干相关的私有具体工厂子类集合到抽象超类之下;

 

b.类簇将一些私有的、具体的子类组合在一个公共的、抽象的超类下面,

以这种方法来组织类可以简化一个面向对象框架的公开架构,

而又不减少功能 的丰富性;

 

c.NSString NSArray NSDictionary NSNumber都是[类簇/工厂类]

不能被继承,即使被继承,也不能使用父类的方法。

 

2 点语法和属性关键词@property 的使用

 

-》点语法与setter/getter 的关系

点语法和@property 关键字的使用,

是对于setter/getter方法的语法替代;

其原理,类似 C 语言中的,是在程序的编译阶段被替代。

该替代,为文本替代,不去检查程序的逻辑语义。

 

a.只要一个类有符合要求的setter/getter方法那么就可以使用'.'操作

 

b.xiaohong.name = @"xiaohong"; 这里实际上调用的是setter方法

NSString *nameString = xiaohong.name;这里实际上调用的是getter方法

 

c. id 类型不能直接使用点操作(需要强制类型转换)

 

-》属性@property

a. @property自动声明setter和getter方法

    @synthesize自动实现setter和getter方法

 

b.  @property NSUInteger x;创建下述两个方法

- (void)setX:(NSUInteger)x;

- (NSUInteger)x;

 

@synthesize x = _x;//实现下述两个方法 Xcode4.6以后可以省略

- (void)setX:(NSUInteger)x

{

    _x = x;

}

 

- (NSUInteger)x

{

    return _x;

}

-》属性修饰符

//只读修饰符

//只有getter方法,没有setter方法

@property (readonly) NSString * name;

 

//直接赋值修饰符(缺省)

@property (assign) NSString * name;

 

//读写修饰符(缺省)

//同时创建set方法和get方法

@property (readwrite) NSString * address;

 

//原子操作修饰符(缺省)

@property (atomic) NSString * group;

 

//非原子操作

@property (nonatomic) NSString * grade;

 

//多个属性修饰符,需要用逗号隔开

@property (nonatomic, readonly, getter = birth) NSString * birthDay;

 

//给set方法和get方法起别名

@property (getter = personAge, setter = setAgi:) int age;

 

3. 类别/类目 Category

(1)增补既有类的方法,它是具名

(2)不能添加新的属性

(3)包括NSString,NSDictionary,NSArray,NSNumber内所有的类都能扩展,都能使用category

 

-》类别的基本语法

 

//类别的声明部分@interface  NSString(Print)-(void)print;//增加的新方法(不能有成员变量的声明)...@end //类别实现部分@implementation NSString(Print)-(void)print{ }…@end

 

注:一旦使用类别给已有的类增补方法,那么这个类的对象就可以使用这个方法

 

-》.类别功能:

  a. 可以给已有/ 系统原生的类增补方法

 

  b.可以对类的方法进行分类管理,

    可以将类的实现分散到多个不同文件或多个不同框架中。

 

-》使用类别需要注意的问题

a.类别中不能添加成员变量

 

b.使用类别增补的方法须导入类别头文件

 

c.父类类别中的方法,子类也可以用

 

-》类扩展/匿名类别 (class extend)

    当不想对外公开一些类的方法时,我们可以使用类扩展

 

a.类扩展的基本语法

类扩展的声明写在.m文件中

  

@interface Person()//没有名字  - (void)song;@end @implementation Person- (void)song{NSLog(@"hello");}@end

 

注:

类扩展只有声明部分,没有实现部分 。

类扩展中声明的方法需要在类的实现部分实现

 

b.类扩展的功能

1.可以实现私有方法

2.方便程序员调用不公开的方法

3.可以声明成员变量

 

eg.示例代码

Account.h文件

#import <Foundation/Foundation.h>#define RATE 0.0325@interface Account : NSObject{  NSUInteger _uid;//用户账号  NSString* _upasswd;//用户密码  double _uamount;//账户余额  double _uperiod;//储蓄时间  double _rate;//一年期的存款利率}@property (assign,nonatomic) NSUInteger uid;@property (copy,nonatomic) NSString* upasswd;@property (assign,nonatomic) double uamount;@property (assign,nonatomic) double uperiod;@property (assign,nonatomic) double rate;- (void)deposit:(double)money;//存款- (double)withdraw:(double)money;//提款- (double)settlementOnWithdraw:(double)money;//取款时结算利息- (double)settlementUponYear;//年度结算利息- (double)interestCaculate;//利息计算- (double)incomeCaculate;//到期本息收益+ (void)testBySelf;//本类的自测方法- (id)initWithUid:(NSUInteger)aUid andUpasswd:(NSString*)aUpasswd andUamount:(double)aUamount;@end

 

Account+currency.h文件

#import "Account.h"@interface Account (currency)- (void)deposit:(double)money withForeignCurrency:(char)type;//存款- (double)withdraw:(double)money withForeignCurrency:(char)type;//提款@end

 

Account.m文件

#import "Account.h"#import "Account+currency.h"  //#include "Account_dollar.h"@implementation Account@synthesize uid=_uid;@synthesize uamount=_uamount;@synthesize upasswd=_upasswd;@synthesize rate=_rate;@synthesize uperiod=_uperiod;- (void)deposit:(double)money{  _uamount += money;  NSLog(@"存款后的当前账户余额:%.2lf",_uamount);}- (double)withdraw:(double)money{  _uamount += [self settlementOnWithdraw:_uamount];  _uamount -= money;  NSLog(@"取款后的当前账户余额:%.2lf",_uamount);  return _uamount;}- (double)settlementOnWithdraw:(double)money//取款时结算利息{  double RetMoney = money;    return RetMoney *= (_rate * _uperiod);}- (double)settlementUponYear//年度结算利息{    return _uamount *= (1+_rate);}- (double)interestCaculate//到期利息计算{  double interest = 0.0;    return interest = _uamount * _rate;}- (double)incomeCaculate//到期本息收益{  double income = 0.0;  return income = _uamount*(1+_rate);}+ (void)testBySelf//本类的自测方法{    //新建一个账户实例  Account* aAccount = [[Account alloc]init];    //显示账户初始状态  NSLog(@"%@",aAccount);    //存款测试  [aAccount deposit:100.00];  NSLog(@"%@",aAccount);    //模拟的日期间隔  int n = 36;  for(int i=1;i<=n;i++){    aAccount.uperiod = (double)i/(double)365;  }    //取款测试  [aAccount withdraw:50.00];  NSLog(@"%@",aAccount);    //模拟存一笔前,并到一年期  [aAccount deposit:100.00];    //模拟时间流逝  for(int i=n;i<=365;i++){    aAccount.uperiod = (double)i/(double)356;  }  [aAccount settlementUponYear];   NSLog(@"%@",aAccount);    //外币存款//  aAccount.foreign_amount = 1.0;  [aAccount deposit:200.00 withForeignCurrency:'$'];  }- (id)initWithUid:(NSUInteger)aUid andUpasswd:(NSString*)aUpasswd andUamount:(double)aUamount{  if (self = [super init]) {    _rate = RATE;    _uperiod = 1/365;    _uid = aUid;    _upasswd = aUpasswd;    _uamount = aUamount;  }    return self;}-(id)init{  return [self initWithUid:1 andUpasswd:@"123456" andUamount:1.0];}- (NSString *)description{  NSString* passwd_des = @"******";    return [NSString stringWithFormat:@"用户账号:%06lu 用户口令:%@ 账户余额:%.2lf(元) 当前定期存款利率(一年期):%.4lf 存储时间:%.2lf(年)", _uid,passwd_des,_uamount,_rate,_uperiod];}@end

 

Account+currency.m文件

#import "Account+currency.h"#import "Account_dollar.h"@implementation Account (currency)  //外币存款方法- (void)deposit:(double)money withForeignCurrency:(char)type//存款{  double fa = self.foreign_amount;  fa += money;  self.foreign_amount = fa;  NSLog(@"存款后的当前外币(%c)账户余额:%.2lf",type,self.foreign_amount);}  //外币取款方法有 bug,请自行修改正确!!!- (double)withdraw:(double)money withForeignCurrency:(char)type//提款{  self.foreign_amount += [self settlementOnWithdraw:self.foreign_amount];  self.foreign_amount -= money;  NSLog(@"取款后的当前外币(%c)账户余额:%.2lf",type,self.foreign_amount);  return self.foreign_amount;}@end

 

Account_dollar.h文件

#import "Account.h"@interface Account (){  char _currency_type;  double _foreign_rate;  double foreign_amount;}@property (assign) char currency_type;@property (assign) double foreign_rate;@property (assign) double foreign_amount;@end

 

0 0
原创粉丝点击