OC基礎--對成員變數的封裝,oc--變數封裝
#import <Foundation/Foundation.h>//日期結構體typedef struct{ int year; int month; int day;} Date;@interface School : NSObject{ //@public NSString * _name; NSString * _address; Date _createTime;}- (void) introduction;@end
#import "School.h"@implementation School- (void)introduction{ NSLog(@"學校名稱:%@, 學校地址:%@, 創辦時間:%i 年 %i月 %i日", [self name], [self address], [self createTime].year, [self createTime].month,[self createTime].day);}@end
#import <Foundation/Foundation.h>#import "School.h"int main(int argc, const char * argv[]) { School * s = [School new]; s->_name = @"科技大學"; s->_address = @"XX省XX市XX區XX路XX號"; s->_createTime.year = 2045; s->_createTime.month = 13; s->_createTime.day = 34; [s introduction]; return 0;}
如果成員變數是public, 給成員變數賦值的時候, 賦予的值不受我們的約束, 在外部可以隨便讀寫 外界有可能賦值一些髒資料
封裝:
屏蔽內部實現的細節, 僅僅對外提供共有的方法/介面
好處:保證資料的安全性 將變化隔離
規範: 將不需要對外提供的內容都隱藏起來,把屬性都隱藏,提供公用的方法對其訪問
Getter - Setter方法:
setter方法:
作用: 設定成員變數的值
格式:
1. setter方法一定是對象方法
2. 一定沒有傳回值
3. 一定以set開頭, 並且set後面跟上需要設定的成員變數的名稱去掉底線, 並且首字母大寫
4. 一定有參數, 參數類型一定和需要設定的成員變數的類型一致, 並且參數名稱就是成員變數的名稱去掉底線
//成員變數以底線開頭的好處,就是可以區分局部變數和成員變數 - (void) setName: (NSString *) name{ //可在這裡添加驗證代碼對傳入的資料做驗證 _name = name; }
getter方法:
作用: 擷取成員變數的值
格式:
1. getter方法一定是對象方法
2.一定有傳回值, 而且傳回值一定和擷取的成員變數的類型一致
3.方法名稱就是擷取的成員變數的名稱去掉底線
4. 一定沒有參數
- (NSString* ) name{ return _name; }
> 一個屬性可以只有getter方法, 沒有setter方法, 這種屬性我們稱之為唯讀屬性
> 一個屬性也可以只有setter方法, 沒有getter方法, 這種屬性我們稱之為唯寫屬性
> 如果既有setter方法又有getter方法, 那麼這種屬性我們稱之為可讀可寫的屬性
> 一個屬性也可以沒有getter和setter, 這種屬性我們稱之為私人屬性
Getter - Setter 方法的調用:
Date date = {1990, 1, 1}; School * s = [School new]; [s setName:@"test"]; [s setAddress:@"tset"]; [s setCreateTime:date]; NSLog(@"學校名:%@", [s name]);
點文法:
> 如果給屬性提供了getter和setter方法, 那麼訪問屬性就又多了一種訪問方式 , 點文法
> 點文法其實它的本質就是調用setter和getter方法
> 點文法是一個編譯器的特性, 會在程式翻譯成二進位的時候將.文法自動轉換為setter和getter方法的調用
> 如果點文法在=號的左邊, 那麼編譯器會自動轉換為setter方法
> 如果點文法在=號的右邊, 或者沒有等號, 那麼編譯器就會自動轉換為getter方法
s.name = @"test"; // 等效於 [s setName:@"test"]; s.address = @"測試"; // 等效於 [s setAddress:@"測試"]; s.createTime = date; // 等效於 [s setCreateTime:date]; NSLog(@"學校名:%@, 學校地址:%@", s.name, s.address); // 等效於 NSLog(@"學校名:%@, 學校地址:%@", [s name], [s address]);
> 點文法一般用於給成員變數賦值, 如果不是給成員變數賦值一般情況下不建議使用, 但是也可以使用
- (void)test:(int)num{ NSLog(@"測試資料 %i", num); } s.test; // 等效於 [s test]
#import <Foundation/Foundation.h>//日期結構體typedef struct{ int year; int month; int day;} Date;@interface School : NSObject{ //@public NSString * _name; NSString * _address; Date _createTime;}-(void) setName: (NSString *) name;-(NSString* ) name;- (void) setAddress: (NSString *) address;- (NSString *) address;- (void) setCreateTime: (Date) date;- (Date) createTime;- (void) introduction;- (void) test;- (void) test: (int) num;@end#import "School.h"@implementation School-(void) setName: (NSString *) name{ //可在這裡添加驗證代碼對傳入的資料做驗證 _name = name;}- (NSString* ) name{ return _name;}- (void) setAddress: (NSString *) address{ _address = address;}- (NSString *) address{ return _address;}- (void) setCreateTime: (Date) date{ _createTime = date;}- (Date) createTime{ return _createTime;}- (void)introduction{ NSLog(@"學校名稱:%@, 學校地址:%@, 創辦時間:%i 年 %i月 %i日", [self name], [self address], [self createTime].year, [self createTime].month,[self createTime].day);}//測試點文法訪問非getter-setter方法- (void)test{ NSLog(@"點文法調用無參對象方法");}- (void)test:(int)num{ NSLog(@"測試資料 %i", num);}@end#import <Foundation/Foundation.h>#import "School.h"int main(int argc, const char * argv[]) { //School * s = [School new];// s->_name = @"科技大學";// s->_address = @"XX省XX市XX區XX路XX號";// s->_createTime.year = 2045;// s->_createTime.month = 13;// s->_createTime.day = 34; Date date = {1990, 1, 1}; School * s = [School new]; s.name = @"test"; // 等效於 [s setName:@"test"]; s.address = @"測試"; // 等效於 [s setAddress:@"測試"]; s.createTime = date; // 等效於 [s setCreateTime:date]; NSLog(@"學校名:%@, 學校地址:%@", s.name, s.address); // 等效於 NSLog(@"學校名:%@, 學校地址:%@", [s name], [s address]); // 點文法調用無參對象方法警告資訊: Property access result unused - getters should not be used for side effects s.test; // 等效於 [s test]; // 點文法調用帶參對象方法 編譯直接報錯 s.test:111; [s introduction]; return 0;}