麻豆小视频在线观看_中文黄色一级片_久久久成人精品_成片免费观看视频大全_午夜精品久久久久久久99热浪潮_成人一区二区三区四区

首頁 > 學(xué)院 > 開發(fā)設(shè)計(jì) > 正文

objective-c語法快速過(3)

2019-11-14 19:30:29
字體:
供稿:網(wǎng)友

oc 里的匿名對象 

 oc 這里,很少用到,因?yàn)椴⒉贿m用于oc的內(nèi)存管理,只是面試筆試也許出現(xiàn),要求能看懂,不要在項(xiàng)目里這樣寫,因?yàn)閷懩涿麑ο螅瑫?huì)造成內(nèi)存泄露

#import <Foundation/Foundation.h>@interface Car : NSObject{    @public    int speed;}- (void)run;@end@implementation Car- (void)run{    NSLog(@"%d", speed);}@endint main(){    //所謂匿名對象,就是沒有名字的對象,看不到,但是對象確實(shí)存在    [Car new]->speed = 300;//沒有指針變量指向?qū)ο螅侵苯诱{(diào)用類的成員變量,因?yàn)槊看问褂肹Car new]都會(huì)從新創(chuàng)建一個(gè)新對象,故不是300,而是默認(rèn)初始化的值0    [[Car new] run];//0       // Car *c = [Car new];   // c->speed = 100;   // [c run];//100    return 0;}

能看懂什么意思就行

類的成員變量的命名規(guī)范

  • 成員變量都以下劃線 _ 開頭
  • 可以跟get方法的名稱區(qū)分開
  • 可以跟其他局部變量區(qū)分開,一看到下劃線開頭的變量,肯定是類的成員變量

OC弱語法

1、OC是動(dòng)態(tài)檢測錯(cuò)誤,OC里調(diào)用一個(gè)沒有聲明也沒有實(shí)現(xiàn)的對象方法,則不會(huì)編譯報(bào)錯(cuò)而是警告,鏈接也能通過,只有運(yùn)行才檢測出錯(cuò)

2、Oc里調(diào)用只有聲明,但是沒有實(shí)現(xiàn)的對象方法,這編譯也是警告,鏈接通過,運(yùn)行才出錯(cuò)

3、Oc調(diào)用只有實(shí)現(xiàn)(沒聲明)的方法,則沒有問題!因?yàn)檫\(yùn)行時(shí)才檢測程序的問題,聲明其實(shí)只是擺設(shè),刪掉是沒事的。只不過開發(fā)中,必須規(guī)范!該寫都要寫上。即使不報(bào)錯(cuò)。

類方法

直接可以用類名來執(zhí)行的方法(類本身會(huì)在內(nèi)存中占據(jù)存儲(chǔ)空間,里面有類/對象方法列表)

1.  類方法和對象方法對比

1)   對象方法

  • 減號-開頭
  • 只能讓對象調(diào)用,沒有對象,這個(gè)方法根本不可能被執(zhí)行
  • 對象方法能訪問實(shí)例變量(成員變量)

2)   類方法

  • 加號+開頭
  • 只能用類名調(diào)用,對象不能調(diào)用
  • 類方法中不能訪問實(shí)例變量(成員變量)
  • 使用場合:當(dāng)不需要訪問成員變量的時(shí)候,盡量用類方法

3)       類方法和對象方法可以同名

4)       提高程序性能

類方法的好處和使用場合:不依賴于對象,執(zhí)行效率高, 能用類方法,盡量用類方法

// 類方法都是以+開頭+ (void)PRintClassName;- (void)test;+ (void)test; //可以允許類方法和對象方法同名

self 關(guān)鍵字用來指明對象是當(dāng)前方法的接收者。 

  • 當(dāng)成員變量和局部變量同名時(shí),采取就近原則,訪問的是局部變量
  • 用self訪問成員變量,區(qū)分同名的局部變量

細(xì)節(jié):

1)    出現(xiàn)的地方:可以出現(xiàn)在所有的OC方法中(對象方法/類方法),但是不能出現(xiàn)在函數(shù)里

2)    作用:

使用 "self->成員變量名" 訪問當(dāng)前方法調(diào)用的成員變量

使用 "[self 方法名];" 來調(diào)用方法(對象方法/類方法)

#import <Foundation/Foundation.h>@interface Person : NSObject{    int _age;}- (void)setAge:(int)age;- (int)age;- (void)test;@end@implementation Person- (void)setAge:(int)age{    // _age = age;相當(dāng)于    self->_age = age;}- (int)age{    return self->_age;}- (void)test{    // self:指向了方向調(diào)用者,代表著當(dāng)前對象    int _age = 20;    NSLog(@"Person的年齡是%d歲", self->_age);}@endint main(){    Person *p = [Person new];        [p setAge:10];        [p test];        return 0;}/* self的用途: 1> 誰調(diào)用了當(dāng)前方法,self就代表誰 * self出現(xiàn)在對象方法中,self就代表對象 * self出現(xiàn)在類方法中,self就代表類 2> 在對象方法利用"self->成員變量名"訪問當(dāng)前對象內(nèi)部的成員變[self 方法名]可以調(diào)用其他對象方法/類方法 */#import <Foundation/Foundation.h>@interface Dog : NSObject- (void)bark;- (void)run;@end@implementation Dog- (void)bark{    NSLog(@"汪汪汪");}- (void)run{    [self bark];//self代表指針d指向的對象,NSLog(@"汪汪汪");    NSLog(@"跑跑跑");}@endint main(){    Dog *d = [Dog new];        [d run];        return 0;}

低級錯(cuò)誤:

用self去調(diào)用函數(shù)

類方法中用self調(diào)用對象方法,對象方法中用self調(diào)用類方法

self死循環(huán)

#import <Foundation/Foundation.h>@interface Person : NSObject- (void)test;+ (void)test;- (void)test1;+ (void)test2;- (void)haha1;+ (void)haha2;@end@implementation Person- (void)test{    NSLog(@"調(diào)用了-test方法");    // 如果有[self text];這句,就會(huì)引發(fā)死循環(huán)。因?yàn)閇self test];self代表對象,一直調(diào)用對象方法test}+ (void)test{    NSLog(@"調(diào)用了+test方法");    // 引發(fā)死循環(huán) [self test];self代表類,一直調(diào)用類方法test}//自動(dòng)識(shí)別- (void)test1{    [self test]; // ok,-test}+ (void)test2{    [self test]; // ok,+test}- (void)haha1{    NSLog(@"haha1-----");}//函數(shù)void haha3(){  }+ (void)haha2{     haha3();//ok,一定注意函數(shù)和方法是不一樣的!    //[self haha3];//error,不能用self調(diào)用函數(shù)    //[self haha1];//error,類方法里,不能用self調(diào)用對象方法,相反,在對象方法里,也不能用self調(diào)用類方法}@endint main(){    [Person haha2];//直接調(diào)用類方法    //Person *p = [Person new];    //[p test1];    return 0;}

 

原則上(如果不使用 ARC,也就是自動(dòng)引用計(jì)數(shù)),那么

創(chuàng)建一個(gè)新對象,都要請求分配內(nèi)存,在完成對該對象的操作時(shí),必須釋放其所用的內(nèi)存空間。類似 c++的內(nèi)存管理。

 

與 C 語言兼容的地方:

預(yù)處理:

#define 語句和 c 一樣

#運(yùn)算符: #define str(x) #x

表示在調(diào)用該宏時(shí),預(yù)處理程序根據(jù)宏參數(shù)創(chuàng)建C 風(fēng)格的常量字符串。

例如:str("hello")將產(chǎn)生"/"hello"/"

##運(yùn)算符:表示用于把兩個(gè)標(biāo)記連在一起

#import 語句;相當(dāng)于#include 語句,但是 #import 可自動(dòng)防止同一個(gè)文件被導(dǎo)入多次。

#條件編譯語句(#ifdef 、#endif 、 #else 、 #ifndef)和 C 一樣

#undef 語句 消除特定名稱的定義


其他基本的C 語言特性:

數(shù)組、函數(shù)、指針、結(jié)構(gòu)、聯(lián)合的用法和C 一樣。

Compound Literal 是包含在括號之內(nèi)的類型名稱,之后是一個(gè)初始化列表。

例如

如果 intPtr 為 int * 類型:
intPtr = (int[100]){[0] = 1, [50] = 50, [99] = 99};

如果數(shù)組大小沒有說明,則有初始化列表確定。

其他如循環(huán)語句 (do while、while、for) 、條件語句(if 語句(if-else、復(fù)合判斷條件等) 、switch 語句)、 Boolean(YES NO)、條件運(yùn)算符、goto 語句、空語句、逗號表達(dá)式、sizeof 運(yùn)算符、命令行參數(shù)、位操作都 和 C 一樣 。

oc 的繼承

oc的繼承只支持單一繼承,和java類似,也就是兒子只能有一個(gè)爸爸,但是

可以通過 Objective-C 的分類和協(xié)議特性獲取多繼承的優(yōu)點(diǎn) 

而c++支持單一和多重繼承。

好處:

不改變原來模型的基礎(chǔ)上,拓充方法

建立了類與類之間的聯(lián)系

抽取了公共代碼

壞處:

耦合性強(qiáng)

基本上所有類的根類是NSObject類

如圖:

animal類擁有NSObject類的new方法,子類dog和cat同時(shí)擁有前兩層類的所有方法和屬性。類似 c++和 java

#import <Foundation/Foundation.h>/* 1.繼承的好處: 1> 抽取重復(fù)代碼 2> 建立了類之間的關(guān)系 3> 子類可以擁有父類中的所有成員變量和方法 2.注意點(diǎn) 1> 基本上所有類的根類是NSObject *//********Animal的聲明*******/@interface Animal : NSObject{    int _age;    double _weight;}- (void)setAge:(int)age;- (int)age;- (void)setWeight:(double)weight;- (double)weight;@end/********Animal的實(shí)現(xiàn)*******/@implementation Animal- (void)setAge:(int)age{    _age = age;}- (int)age{    return _age;}- (void)setWeight:(double)weight{    _weight = weight;}- (double)weight{    return _weight;}@end/********Dog*******/// 繼承了Animal,相當(dāng)于擁有了Animal里面的所有成員變量和方法// Animal稱為Dog的父類,Dog稱為Animal的子類@interface Dog : Animal@end@implementation Dog@end/********Cat*******/@interface Cat : Animal@end@implementation Cat@endint main(){    Dog *d = [Dog new];        [d setAge:10];        NSLog(@"age=%d", [d age]);    return 0;}

oc 繼承里的細(xì)節(jié)(類似其他面向?qū)ο笳Z言)

父類必須聲明在子類的前面

子類和父類不能有相同的成員變量,但是方法可以重寫

方法的重寫問題:子類重新實(shí)現(xiàn)父類中的某個(gè)方法,也就是覆蓋了父法

調(diào)用某個(gè)方法時(shí),優(yōu)先去當(dāng)前類中找,如果找不到,去父類中找

這是內(nèi)部原理。

每個(gè)對象都有一個(gè)isa指針,指向?qū)ο髮儆诘念悾矣涀。好總€(gè)類里(oc的)都有一個(gè)superclass指針,指向自己的父類。

這樣通過對象就能找到對象屬于的類,也能找到類的父類。而這些指針就在NSSobject類里。

內(nèi)存結(jié)構(gòu):

繼承的使用場合

 1> 當(dāng)兩個(gè)類擁有相同屬性和方法的時(shí)候,就可以將相同的東西抽取到一個(gè)父類中

 2> 當(dāng)A類完全擁有B類中的部分屬性和方法時(shí),可以考慮讓B類繼承A類

 // 繼承:xx 是 xxx

 // 組合(也叫聚合關(guān)系):xxx 擁有 xxx

super關(guān)鍵字

實(shí)現(xiàn)重寫之后,還可以調(diào)用父類的對象方法和類方法,super的作用;直接調(diào)用父類中的某個(gè)方法

 1、super處在對象方法中,那么就會(huì)調(diào)用父類的對象方法

 2、super處在類方法中,那么就會(huì)調(diào)用父類的類方法

使用場合:

子類重寫父類的方法時(shí)想保留父類的一些行為。

在oc里,簡單的多,調(diào)用某方法,先是在所在類就近找,找不到去父類找。太簡單了。如果重寫了父類方法,那么只能調(diào)用子類重寫的這個(gè)方法了,如果想保留父類原方法定義的功能,可以用super。

oc 的多態(tài)

多態(tài)的體現(xiàn)

Person *p = [Student new];

p->age = 100;

[p walk];

子類對象賦值給父類指針,父類指針訪問對應(yīng)的子類的繼承來的屬性和方法

多態(tài)的局限性

不能訪問子類的特有的屬性或方法(可以考慮強(qiáng)制轉(zhuǎn)換)

多態(tài)的細(xì)節(jié)

動(dòng)態(tài)綁定:在運(yùn)行時(shí)根據(jù)對象的類型確定動(dòng)態(tài)調(diào)用的方法

注意點(diǎn):

 1.沒有繼承就沒有多態(tài)

 2.代碼的體現(xiàn):父類類型的指針指向子類對象

 3.好處:如果函數(shù)/方法參數(shù)中使用的是父類類型,可以傳入父類、或者子類對象

 4.局限性:父類類型的變量 不能 直接調(diào)用子類特有的方法。必須強(qiáng)轉(zhuǎn)為子類類型變量后,才能直接調(diào)用子類特有的方法(類似c++的賦值兼容)

#import <Foundation/Foundation.h>// 動(dòng)物@interface Animal : NSObject- (void)eat;@end@implementation Animal- (void)eat{    NSLog(@"Animal-吃東西----");}@end//@interface Dog : Animal- (void)run;//子類新增的對象方法run@end@implementation  Dog- (void)run{    NSLog(@"Dog---跑起來");}- (void)eat//重寫父類的-eat方法{    NSLog(@"Dog-吃東西----");}@end//@interface Cat : Animal@end@implementation Cat- (void)eat//重寫父類的對象方法eat{    NSLog(@"Cat-吃東西----");}@end// 如果參數(shù)中使用的是父類類型指針,可以傳入父類or子類對象void feed(Animal *a){    [a eat];}int main(){    Animal *aa = [Dog new];//父類指針指向子類的對象    //[aa run];弱語法,只警告!但是在java或者c++里,早就報(bào)錯(cuò)了!父類指針不能訪問子類特有的方法,雖然弱語法,但不推薦,自己要認(rèn)為是錯(cuò)的    // 將父類對象aa轉(zhuǎn)為子類 Dog * 類型的變量就ok了,和c++類似    Dog *dd = (Dog *)aa;    [dd run];//ok,訪問的是子類的對象方法 run         //Dog *d = [Dog new];    //[d run];//ok        /* Animal *aa = [Animal new];父類對象的指針aa    feed(aa);可以傳入父類對象做參數(shù),調(diào)用的父類的eat方法    Dog *dd = [Dog new];子類對象指針dd    feed(dd); 也可以傳入子類的對象做參數(shù),調(diào)用的子類的eat方法    Cat *cc = [Cat new];    feed(cc);調(diào)用子類eat,傳入子類對象參數(shù)   */    // 多態(tài):父類指針指向子類對象    Animal *a = [Dog new];    // 調(diào)用方法時(shí)會(huì)檢測對象的真實(shí)形象,動(dòng)態(tài)    [a eat];調(diào)用的時(shí)子類的eat方法    */    return 0;}

多態(tài)的局限性:

父類類型的變量 不能 直接 調(diào)用子類特有的方法。

聯(lián)系c++

c++是使用了虛函數(shù),(包括純虛函數(shù)和抽象類)對公有繼承的子類的方法,重寫虛函數(shù),父類指針或者引用指向子類,那么就能調(diào)用子類的重寫虛函數(shù),指向父類,就是調(diào)用父類的虛函數(shù),實(shí)現(xiàn)動(dòng)態(tài)聯(lián)編。

oc里,沒有那么復(fù)雜,就是直接子類繼承父類,那么重寫父類某個(gè)對象方法,這只需要父類指針指向子類對象,那么就調(diào)用子類的重寫方法,同樣也不能調(diào)用子類特有的方法。

由此斷定,oc的方法都是虛方法!不用和c++一樣用virtual聲明!且oc的重寫也是多態(tài)的一種,oc里所有的方法訪問屬性都是公有的!而類成員變量默認(rèn)是保護(hù)的。和c++有些區(qū)別,c++是默認(rèn)都是私有的。

再看oc的弱語法!比如把子類對象指針指向父類

Cat *cat = [Animal new];

c++里肯定錯(cuò)誤,但oc里沒問題,只警告,但這樣不好,不推薦。完全沒道理。

再看:

NSString *s = [Cat new];

動(dòng)物怎么了成了字符串對象了?oc里xcode不報(bào)錯(cuò)!但是絕對是不對,不規(guī)范。還有,同一個(gè)層次的類,貓類指針指向狗類對象,調(diào)用eat方法,在oc的弱語法下,還是沒問題的,調(diào)狗的eat。

oc太弱了!但是在c++里直接就報(bào)錯(cuò)了。不可以這樣寫,即使編譯器不報(bào)錯(cuò)。

多態(tài)的好處

用父類對象接收參數(shù),方法或者函數(shù),即可以接受子類對象,也能接受父類對象,節(jié)省代碼。否則還要分開寫多個(gè)方法或者函數(shù)。

充分體現(xiàn)面向?qū)ο蟮某橄蠛途唧w,通過子類重寫繼承來的父類的虛方法(oc默認(rèn)都是),通過父類指針指向子類對象,實(shí)現(xiàn)動(dòng)態(tài)多態(tài)性!不看指針的類型,而是看指針指向的哪個(gè)對象類型,就調(diào)用哪個(gè)子類對象的虛方法。注意子類特有的方法不可以,必須強(qiáng)轉(zhuǎn)。

 


發(fā)表評論 共有條評論
用戶名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 成人免费午夜视频 | 欧美日韩国产一区二区三区在线观看 | 一级黄色欧美 | 污视频在线看 | 中文字幕h | 99爱在线免费观看 | 538任你躁在线精品视频网站 | 中文字幕偷拍 | 国内精品国产三级国产a久久 | av中文字幕免费在线观看 | 国产日产精品一区四区介绍 | 欧美黑人伦理 | 国产成人在线播放视频 | 免费a级毛片永久免费 | 毛片成人 | 天天夜夜草 | 亚洲午夜视频 | 国产毛片aaa一区二区三区视频 | 最新黄色毛片 | 高清做爰免费无遮网站挡 | 九九热在线视频观看 | 日韩毛片一区二区三区 | 中文字幕一区二区三区四区 | 色av成人天堂桃色av | 亚洲四播房| 一级黄色片武则天 | 日日噜噜噜夜夜狠狠久久蜜桃 | 欧美人的天堂一区二区三区 | 成人男女啪啪免费观看网站四虎 | 女人叉开腿让男人桶 | 播色网| 亚洲aⅴ免费在线观看 | 日韩a毛片免费观看 | 欧美城网站地址 | 在线免费观看欧美 | 一边吃奶一边摸下娇喘 | 国产精品一品二区三区四区18 | 九九热九九热 | 国产在线精品区 | 精品亚洲在线 | av电影免费看|