程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> C# >> C#入門知識 >> 從C#到Object C,循序漸進學習蘋果開發(2)--Object C和C#的差異

從C#到Object C,循序漸進學習蘋果開發(2)--Object C和C#的差異

編輯:C#入門知識

本隨筆系列主要介紹從一個Windows平台從事C#開發到Mac平台開發蘋果開發的一系列感想和體驗歷程,本系列文章是在起步階段逐步積累的,希望帶給大家更好,更真實的轉換歷程體驗。   在上篇《從C#到Object C,循序漸進學習蘋果開發(1)--准備開發賬號和開發環境》介紹了一些基本的轉換感悟和一些基礎的准備工作,還沒有正式真實的介紹Object C和C#的之前差異,我們知道,從一種環境或者一種語言轉換過去另外一種,我們都會做一些對比和理解,這樣可以很容易把我們頭腦的知識進行對接,在這個所有東西日益大同的背景下,我們相信,所有的語言特點都是相通的。   1、面向對象的類   1)類的定義   Object C(下稱OC)和C#都是面向對象的語言,雖然OC比C#古老,起源自C,但是很多特點和C#都很接近了,在C#3.0裡面才引入的擴展方法,在OC裡面也存在了。   OC和C#都一樣,他們繼承的關系都是單繼承的,沒有C++的那種多重繼承那麼復雜,OC很有特點的一個要求就是把接口和實現完全分開,這點是熟悉C#開發的人員必須轉換過來的思路,在OC裡面,寫一個類,先寫接口定義,然後再寫實現,它的語法和C#很大不同,但是也很容易理解。   OC的關鍵字一般都是以@符號進行標識,這點和C#的默認保留關鍵字不同,一般看到@interface, @property, @關鍵字,在最新版本的XCode裡面,真是發揮到了極致了,包含了很多語法糖,基本上和C#走向了大同,這點在對象的初始化繼續介紹。   OC的類定義放到.h文件裡面,實現放到了.m文件裡面,如下面是類的接口聲明。   @interface SimpleClass : NSObject   @end 而類的實現操作如下所示。   #import "SimpleClass.h"   @implementation SimpleClass   @end 上面只是一個演示類的概念,一般情況下,類都有屬性或者方法,因此還需要增加很多東西。   另外OC和C#對比,沒有了命名空間的概念,OC的類為了避免混淆一般通過前綴進行區分,如你看到的IOS基礎類庫,很多帶有NS,UI,CA,等這樣的前綴,就是這個原因。   2)方法的定義   如下面的接口聲明一個方法,方法的定義   @interface XYZPerson : NSObject - (void)sayHello; @end 我們看到,上面的方法定義(接口定義)很簡單,這裡有一個 - 符號,是用來標識屬於實例方法的,還有一種屬於類級別的方法,用+符號標識,這個加號,類似於C#語言裡面的static關鍵字,默認在方法定義為-的實例方法,都是類似於C#裡面的public方法了。   這個(void)定義是返回值的標識,C#是不需要括號的void標識無返回值,方法最後需要括號標識。   - (void)sayHello;   這個方法的定義沒有參數因此是這樣寫的,如果方法有多個參數,這個OC就很有意思,我感覺這個是OC裡面最有個性的一個地方了。   如果方法如下所示:   - (void) setCaption: (NSString*)input;   類方法的調用是通過空格,而C#通過點進行調用,這點也有所不同,OC通過在一個[]裡面空格進行引用,如下所示。   [object method]; [object methodWithInput:input]; 剛才定義的sayHello方法,它的調用可能就是如下方式了   [self setCaption:@"Default Caption"];   如果方法的定義為多個參數(也叫多重參數),定義如下。   -(void) setNumerator: (int) n andDenominator: (int) d;    那麼方法的調用就很有意思了。   [frac2 setNumerator: 1 andDenominator: 5];    如果還有更多的參數,那麼也就一直使用這樣的累加方式,這個有點接近閱讀習慣,呵呵。   3)參數的定義   說完方法的定義和使用,我們介紹下類裡面的屬性的定義,我們知道C#裡面的屬性定義很簡單了,如   public string Name {get;set;} 回來看看OC如何定義屬性的,一般在.h的接口定義裡,可以這樣定義。   @property NSString *firstName; @property NSString *lastName; 然後在實現類代碼裡面,添加它的對應代碼@synthesize的關鍵字   @synthesize firstName, lastName;  屬性當然也可以指定為只讀的,如下代碼所示   @property (readonly) NSString *fullName; 另外,我們還需要清楚,屬性默認是線程安全的,也就是atomic,還有它是強類型Strong的。   @interface XYZObject : NSObject @property NSObject *implicitAtomicObject;          // atomic by default @property (atomic) NSObject *explicitAtomicObject; // explicitly marked atomic @end 在很多地方,我們使用屬性的時候,都不需要指定它的線程安全特性,因為那樣效率更高,一般的屬性定義代碼如下所示。   @property (strong, nonatomic) IBOutlet UILabel *lblName; @property (strong, nonatomic) IBOutlet UITextField *txtInput; 至於是不是所有的屬性都應該指定為Strong,這個肯定不是的,strong的另外一種類型是weak,它是表示弱類型,強類型和弱類型主要是針對ARC來說的,它是引用計數的范疇,Strong相當於原來的retain。   一般情況下,為了避免一些強類型的對象屬性導致出現相互引用的問題,在代理類和數據源對象,還有一些如UITable的對象屬性,他們的屬性定義必須指定為weak的。       2、對象的類型和初始化工作    在C#裡面,我們知道,它裡面包含了有一些基本類型(Primitive type)和一些包裝後的對象類型,如它的基本類型包括string int char float long double decimal等等,它的對應包裝類型有String Int32 Char Single Int64 Double Decimal等等。   在OC裡面,同樣也有這樣的情況,OC的基本類型繼承自C語言的基礎類型,包括有int float double char 等基礎類型,也有很多NS開頭的引用類型(或者說包裝類型),如NSString NSNumber NSDate NSData NSValue等等,而很多集合類型NSArray NSMutableArray NSDictionary等都需要添加引用類型的對象。   另外和C#的Object對象類似或者動態類型關鍵字dynamic指定的類型一樣,OC裡面包含了一個id的類型,這個是一個不確定的類型,它可以看成是一個任何類型的弱定義。   id類型是一個獨特的數據類型,在概念上,類似java的Object類,可以轉換為任何數據類型。換句話說,id類型變量可以存放任何數據類型的對象。在內部處理上,這種類型被定義為指向對象的指針,實際上是一個指向這種對象的實例變量的指針。需要注意的是id是一個指針,所以在使用id的時候不需要加星號;比如說:id foo=nil;   1)類對象的初始化   我們知道,OC裡面很多都是通過alloc init這樣的方式進行初始化,如下面代碼所示。   XYZObject *object = [[XYZObject alloc] init]; 而C#裡面大多數使用new方式進行初始化,其實OC裡面,也一樣可以通過new方式進行初始化,不過僅限在默認構造函數的方式進行,如下的代碼是等同於上面的語句的。   XYZObject *object = [XYZObject new]; 不過好像很多人都習慣用第一種方式初始化對象。   2)字符串的初始化   相信很多人使用OC的時候,第一個印象最深的我覺得可能是NSString類了,這個是和C#的String有點類似,都是固定的字符串對象,如果需要變化類型的字符串對象,C#裡面是可以使用StringBuffer,而OC裡面可以使用NSMutalbeString,NSMutableString好比一個字符串鏈表,它可以任意的動態在字符串中添加字符串 刪除字符串 指定位置插入字符串,使用它來操作字符串會更加靈活。   字符串的定義和初始化和簡單,我們可以通過下面的方式進行初始化。   NSString *someString = @"Hello, World!"; 我們知道,C#也可以使用@字符進行賦值,雖然一般情況使用在多行的情況下,但是在OC,這個@字符不能省略。   其他數據類型初始化,很多都依靠@字符進行,這個@字符可以說是非常強大的,它也可以說是一個很好的語法糖,如下面初始化各種類型的代碼如下(在OC裡面,NSNumber可以放置任何引用類型)       NSNumber *myBOOL = @YES;     NSNumber *myFloat = @3.14f;     NSNumber *myInt = @42;     NSNumber *myLong = @42L; NSNumber類型可以裝納各種類型,同樣它也可以轉換為其他對應的類型,如下代碼所示   復制代碼    int scalarMagic = [magicNumber intValue];     unsigned int scalarUnsigned = [unsignedNumber unsignedIntValue];     long scalarLong = [longNumber longValue];       BOOL scalarBool = [boolNumber boolValue];       float scalarSimpleFloat = [simpleFloat floatValue];     double scalarBetterDouble = [betterDouble doubleValue];       char scalarChar = [someChar charValue]; 復制代碼     另外,由於OC裡面引入了一個id類型,可以認為它的作用和C# 3.0引入的動態類型相當,它可以在運行時進行確定對象是否具有某個方法,而不會在編譯的時候強制指定。   如下面的代碼編譯通過,運行的時候可能出錯。   id someObject = @"Hello, World!"; [someObject removeAllObjects]; 之所以編譯的時候,不檢查它的對象是否有removeAllObject接口方法,是因為這兒的someObjec指定為了id的動態類型,所以編譯器會不檢查它的方法。       3)對象集合的初始化   剛才上面介紹了字符串等各種類型的初始化,很多采用了強大的關鍵字@進行初始化,這個語法糖減少了很多繁瑣的方法調用,對於集合的初始化,尤其這樣。   如果按照傳統的集合定義方式,一般是通過下面的方法。   NSArray *someArray =   [NSArray arrayWithObjects:someObject, someString, someNumber, someValue, nil]; 在裡面的集合,最後必須加上一個nil的東西,這個在C#的領域裡面是不需要增加這樣的標識的,在Object C裡面,如果你要通過arrayWithObjects方法進行構造,必須增加一個這樣的東西,告訴它這個是最後了,如果你把這個放到第二位,那麼構造的集合也只有兩個對象了,很奇怪了。   如果采用了強大的@方法構造,一切都和C#相似了,這裡你只能佩服它的神奇之處了。   NSArray *someArray = @[firstObject, secondObject, thirdObject]; 如下面定義一個字符串的集合是這樣的。   NSArray *unsortedStrings = @[@"gammaString", @"alphaString", @"betaString"]; 在C#裡面,我們經常用到了字典對象,這個對象非常方便。當然在OC裡面,也肯定會有這樣的東西,畢竟很多語言都會支持的。   這個字典類型也是一個集合類型,它的傳統構造方法如下所示   NSDictionary *dictionary = [NSDictionary dictionaryWithObjectsAndKeys:                    someObject, @"anObject",              @"Hello, World!", @"helloString",                           @42, @"magicNumber",                     someValue, @"aValue",                              nil]; 它這個看起來很怪異,添加指點是按照object,key的這樣方式添加的,這個與我們使用C#的習慣有很大的不同哦,而且最後還帶了一個nil的尾巴。   如果采用@構造函數,一切又都清淨了,已經是key,value方式進行存儲,而且不用nil了,如果你添加了nil,那麼會出錯的。   NSDictionary *dictionary = @{                   @"anObject" : someObject,                @"helloString" : @"Hello, World!",                @"magicNumber" : @42,                     @"aValue" : someValue     }; 集合中,如果取某個對象,那麼通過下面的方法進行獲取    NSNumber *storedNumber = [dictionary objectForKey:@"magicNumber"]; 也可以通過下標括符進行獲取   NSNumber *storedNumber = dictionary[@"magicNumber"]; 如果是一般的數組集合,可以通過下面方式獲取,這種方式和c#很類似了。   1 NSNumber *storedNumber = array[0];     由於時間和篇幅的問題,關於OC的各種和C#對比的特性,以後繼續介紹,OC裡面還涉及很多相關的特點,如擴展方法,協議(類似接口),代碼塊等等內容,以及XCode的各種使用特性,有空繼續介紹。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved