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

 

發佈了24 篇原創文章 · 獲贊 2 · 訪問量 2萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章