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

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

 

posted @ 2014-12-14 15:28  sublimter随想博客  阅读(302)  评论(0编辑  收藏  举报