走在架構(gòu)師的大道上 Jack.Wang's home

          Java, C++, linux c, C#.net 技術(shù),軟件架構(gòu),領(lǐng)域建模,IT 項(xiàng)目管理 Dict.CN 在線(xiàn)詞典, 英語(yǔ)學(xué)習(xí), 在線(xiàn)翻譯

          BlogJava 首頁(yè) 新隨筆 聯(lián)系 聚合 管理
            195 Posts :: 3 Stories :: 728 Comments :: 0 Trackbacks
          很多人說(shuō)C#是微軟用來(lái)和Java抗衡的武器,因?yàn)槎咴诤艽蟪潭壬嫌兄@人的相似
          ,盡管如此,兩者不同的地方也很多,所謂“于細(xì)微處見(jiàn)差異”。那么兩者的相似和區(qū)
          別都在什么地方呢?我們從今天開(kāi)始,會(huì)從各個(gè)角度來(lái)對(duì)比C#和Java的特點(diǎn),希望能對(duì)
          正在學(xué)習(xí)、使用C#的朋友有所幫助。
          1、C#和.NET平臺(tái)的概貌
            2000年6月,微軟發(fā)布C#語(yǔ)言和.NET平臺(tái)。C#語(yǔ)言是一種強(qiáng)類(lèi)型的,面向?qū)ο蟮恼Z(yǔ)言
          ,它具有語(yǔ)法簡(jiǎn)單、表達(dá)力強(qiáng)的特點(diǎn),而.NET平臺(tái)則是構(gòu)成微軟的“.NET計(jì)劃”的基石

            .NET平臺(tái)的核心包括兩方面,一方面就是著名的通用語(yǔ)言運(yùn)行機(jī)(Common Language
          Runtime),雖然這個(gè)名詞起得晦澀了點(diǎn),不過(guò)大家可以拿它和Java的虛擬機(jī)來(lái)作比較,
          二者完成的任務(wù)大致相同;另一方面就是一大堆通用函數(shù)庫(kù),這些庫(kù)函數(shù)可以被多種語(yǔ)
          言調(diào)用,并且通過(guò)編譯都產(chǎn)生一種共同的中間語(yǔ)言(Intermediate Language),這種語(yǔ)
          言也可以拿Java的字節(jié)碼來(lái)類(lèi)比,雖然完成的方式有些不一樣。
          2、C#和Java
            下面簡(jiǎn)單地把C#和Java的相似處列出來(lái),雖然在這里我們重點(diǎn)討論的是C#和Java的
          不同點(diǎn),但是了解一下二者的相同之處也是很有必要的。
            二者都編譯成跨平臺(tái)的、跨語(yǔ)言的代碼,并且代碼只能在一個(gè)受控制的環(huán)境中運(yùn)行

            自動(dòng)回收垃圾內(nèi)存,并且消除了指針(在C#中可以使用指針,不過(guò)必須注明unsafe
          關(guān)鍵字)
            都不需要頭文件,所有的代碼都被“包(package)”限制在某個(gè)范圍內(nèi),并且因?yàn)闆](méi)
          有頭文件,所以消除了類(lèi)定義的循環(huán)依賴(lài)
            所有的類(lèi)都是從對(duì)象派生出來(lái),并且必須使用New關(guān)鍵字分配內(nèi)存
            用對(duì)象加鎖的方式來(lái)支持多線(xiàn)程
            都具有接口(interface)的概念
          內(nèi)部類(lèi)
            繼承類(lèi)的時(shí)候不會(huì)以某種特定的訪(fǎng)問(wèn)權(quán)限來(lái)繼承;
            沒(méi)有全局函數(shù)或者常量,一切必須屬于類(lèi);
            數(shù)組或者字符串都自帶長(zhǎng)度計(jì)算和邊界檢查;
            只使用“.”操作符,沒(méi)有“->”和“::”;
            “null”、“boolean”和“bool”成為了關(guān)鍵字;
            任何變量均在使用前進(jìn)行初始化;
            不能使用整數(shù)來(lái)返回到if條件語(yǔ)句中,必須使用布爾值;
            “Try”模塊后可以有“finally” ;
          3. 屬性(Property)
            屬性的概念對(duì)大家來(lái)說(shuō)應(yīng)該是很熟悉的,類(lèi)成員函數(shù)可以自由地訪(fǎng)問(wèn)本類(lèi)中的任何
          屬性成員。不過(guò)若要從一個(gè)類(lèi)中去訪(fǎng)問(wèn)另一個(gè)類(lèi)中的屬性,那就比較麻煩了,所以很多
          時(shí)候我們使用Getxxx和Setxxx方法,這樣看起來(lái)顯得極不自然,比如用Java或者C++,代
          碼是這樣的:
            foo.setSize (getSize () + 1);
            label.getFont().setBold (true);
            但是,在C#中,這樣的方法被“屬性化”了。同樣的代碼,在C#就變成了:
            foo.size++;
            label.font.bold = true;
            可以看出來(lái),C#顯然更容易閱讀和理解。我們從這個(gè)“屬性方法”的子程序代碼中
          ,也可以看到類(lèi)似情況:
          Java/C++:
          public int getSize()
          {
            return size;
          }
          public void setSize (int value)
          {
            size = value;
          }
          C#:
          public int Size
          {
           get{return size;}
           set{size = value;}
          }
            為了區(qū)分這種屬性化的方法和類(lèi)的屬性成員,在C#中把屬性成員稱(chēng)作“域(field)”
          ,而“屬性”則成為這種“屬性化的方法”專(zhuān)用的名詞。順便說(shuō)一句,其實(shí)這樣的屬性
          化方法在VB和DELPHI中是經(jīng)常碰到的,在VB中它也就叫屬性。
            另外,在C#中Get和Set必須成對(duì)出現(xiàn),一種屬性不能只有Get而沒(méi)有Set(在Java和
          C++中就可以只有Get或者只有Set),C#中這樣做的好處在于便于維護(hù),假如要對(duì)某種屬
          性進(jìn)行修改,就會(huì)同時(shí)注意Get和Set方法,同時(shí)修改,不會(huì)改了這個(gè)忘了那個(gè)。
          4、對(duì)象索引機(jī)制(Indexer)
            C#中引入了對(duì)象索引機(jī)制。說(shuō)得明白點(diǎn),對(duì)象索引其實(shí)就是對(duì)象數(shù)組。這里和上一
          節(jié)中的屬性聯(lián)系起來(lái)講一下,屬性需要隱藏Get和Set方法,而在索引機(jī)制中,各個(gè)對(duì)象
          的Get或者Set方法是暴露出來(lái)的。比如下面的例子就比較清楚地說(shuō)明了這一點(diǎn)。
          public class Skyscraper
          {
           Story[] stories;
           public Story this [int index] {
            get {
             return stories [index];
            }
            set {
             if (value != null) {

              stories [index] = value;
             }
            }
           }
          ...
          }
          5. 指代(Delegate)
            指代這個(gè)玩意很特別,它有點(diǎn)象指針,但又不完全是,不過(guò)大家還是可以把它理解
          為一種類(lèi)型安全的、面向?qū)ο蟮闹羔槨#ㄊ裁词穷?lèi)型安全和面向?qū)ο缶筒挥弥v了吧?)
          順便提一句,有很多書(shū)上把Delegate翻譯成代理,我覺(jué)得這樣翻不夠確切,翻譯成“指
          代”更恰當(dāng)些,道理上吻合,并且還符合它的本來(lái)意思——微軟本來(lái)就是用Delegate來(lái)
          “取代指針”,所以叫“指代”,呵呵。
            說(shuō)起指代,也許至今Sun還會(huì)對(duì)它憤憤不已,為什么呢?因?yàn)樵赟un的標(biāo)準(zhǔn)Java中是
          沒(méi)有這個(gè)東西的,它是微軟99年發(fā)布的MSVJ++6添加的“新特性”。為此,兩家公司吵得
          不亦樂(lè)乎,并且還專(zhuān)門(mén)在網(wǎng)上寫(xiě)了大量文章互相攻擊,有興趣的朋友可以去看看(只有
          英文版)。
          http://www.Javasoft.com/docs/white/delegates.html
          http://msdn.microsoft.com/visualj/technical/articles/delegates/truth.asp
            話(huà)歸正傳,指代有什么特點(diǎn)呢?一個(gè)明顯的特點(diǎn)就是它具有了指針的行為,就好象
          從Java又倒回到了C++。在C#中,指代完成的功能大概和C++里面的指針,以及Java中的
          接口相當(dāng)。但是,指代比起C++的“正宗指針”來(lái)又要高明一些,因?yàn)樗梢酝瑫r(shí)擁有多
          個(gè)方法,相當(dāng)于C++里面的指針能同時(shí)指向多個(gè)函數(shù),并且是類(lèi)型安全的,這一點(diǎn)體現(xiàn)了
          它的“對(duì)象”特性;而比起Java的接口來(lái),指代高明的地方在于它能可以不經(jīng)過(guò)內(nèi)部類(lèi)
          就調(diào)用函數(shù),或者用少量代碼就能調(diào)用多種函數(shù),這一點(diǎn)體現(xiàn)了它的“指針”特性。呵
          呵,很有“波粒二象性”的味道吧?指代最重要的應(yīng)用在于對(duì)于事件的處理,下一節(jié)我
          們將重點(diǎn)介紹。
          6、事件(Event)
            C#對(duì)事件是直接支持的(這個(gè)特點(diǎn)也是MSVJ所具有的)。當(dāng)前很多主流程序語(yǔ)言處
          理事件的方式各不相同,Delphi采用的是函數(shù)指針(這在Delphi中的術(shù)語(yǔ)是“closure”
          )、Java用改編類(lèi)來(lái)實(shí)現(xiàn)、VC用WindowsAPI的消息系統(tǒng),而C#則直接使用delegate和ev
          ent關(guān)鍵字來(lái)解決這個(gè)問(wèn)題。下面讓我們來(lái)看一個(gè)例子,例子中會(huì)給大家舉出聲明、調(diào)用
          和處理事件的全過(guò)程。
          //首先是指代的聲明,它定義了喚醒某個(gè)函數(shù)的事件信號(hào)
          public delegate void ScoreChangeEventHandler (int newScore, ref bool cancel)
          ;
          //定義一個(gè)產(chǎn)生事件的類(lèi)
          public class Game
          {
           // 注意這里使用了event關(guān)鍵字
           public event ScoreChangeEventHandler ScoreChange;
            int score;
            // Score 屬性
            public int Score
            {
             get {
              return score;
             }
             set {
              if (score != value)
              {
               bool cancel = false;
               ScoreChange (value, ref cancel);
               if (! cancel)
               score = value;
              }
            }
          }
          // 處理事件的類(lèi)
          public class Referee
          {
           public Referee (Game game)
           {
            // 裁判負(fù)責(zé)調(diào)整比賽中的分?jǐn)?shù)變化
            game.ScoreChange += new ScoreChangeEventHandler (game_ScoreChange);
           }
           // 注意這里的函數(shù)是怎樣和ScoreChangeEventHandler的信號(hào)對(duì)上號(hào)的
           private void game_ScoreChange (int newScore, ref bool cancel)
           {
            if (newScore < 100)
             System.Console.WriteLine ("Good Score");
            else
            {
             cancel = true;
             System.Console.WriteLine ("No Score can be that high!");
            }
           }
          }
          // 主函數(shù)類(lèi),用于測(cè)試上述特性
          public class GameTest
          {
           public static void Main ()
           {
            Game game = new Game ();
            Referee referee = new Referee (game);
            game.Score = 70;
            game.Score = 110;
           }
          }
            在主函數(shù)中,我們創(chuàng)建了一個(gè)game對(duì)象和一個(gè)裁判對(duì)象,然后我們通過(guò)改變比賽分
          數(shù),來(lái)觀察裁判對(duì)此會(huì)有什么響應(yīng)。
            請(qǐng)注意,我們的這個(gè)系統(tǒng)中,Game對(duì)象是感覺(jué)不到裁判對(duì)象的存在的,Game對(duì)象在
          這里只負(fù)責(zé)產(chǎn)生事件,至于有誰(shuí)會(huì)來(lái)傾聽(tīng)這個(gè)事件,并為之作出反應(yīng),Game對(duì)象是不作
          任何表態(tài)的。
            我們注意到,在裁判類(lèi)的Referee函數(shù)中,Game.ScoreChange后面使用了+=和-=操作
          符,這是什么意思呢?回到我們定義ScoreChange的地方,可以發(fā)現(xiàn)ScoreChange是用ev
          ent關(guān)鍵字修飾的,那么這里的意思就很明白了:ScoreChange是一個(gè)事件,而事件被觸
          發(fā)后需要相應(yīng)的事件處理機(jī)制,+=/-=就是為這個(gè)事件增加/移除相對(duì)應(yīng)的事件處理程序
          ,而且,并不是一個(gè)事件只能對(duì)應(yīng)一個(gè)處理程序,我們還可以用這兩個(gè)操作符為同一事
          件增加/移除數(shù)個(gè)事件處理程序。怎么樣?很方便吧!
            在實(shí)際應(yīng)用中,和我們上面講的(競(jìng)賽-裁判)機(jī)制很相近的系統(tǒng)就是圖形用戶(hù)界面
          系統(tǒng)了。Game對(duì)象可以看作是圖形界面上的小零件,而得分事件就相當(dāng)于用戶(hù)輸入事件
          ,而裁判就相當(dāng)于相應(yīng)的應(yīng)用程序,用于處理用戶(hù)輸入。
            指代機(jī)制的首次亮相是在MSVJ里,它是由Anders Hejlsberg發(fā)明的,現(xiàn)在又用到了
          C#中。指代用在Java語(yǔ)言中的后果,則直接導(dǎo)致了微軟和Sun之間對(duì)類(lèi)和指針的關(guān)系產(chǎn)生
          了大量的爭(zhēng)論和探討。有意思的是,Java的發(fā)明者James Gosling非常幽默地稱(chēng)呼指代的
          發(fā)明者Anders Hejlsberg為“‘函數(shù)指針’先生”,因?yàn)锳nders Hejlsberg總是想方設(shè)
          法地把指針變相地往各種語(yǔ)言中放;不過(guò)有人在看了Java中大量地使用了各種類(lèi)后,也
          戲稱(chēng)Java的發(fā)明者James Gosling為“‘全都是類(lèi)’先生”,真是其中滋味,盡在不言中
          啊。




          本博客為學(xué)習(xí)交流用,凡未注明引用的均為本人作品,轉(zhuǎn)載請(qǐng)注明出處,如有版權(quán)問(wèn)題請(qǐng)及時(shí)通知。由于博客時(shí)間倉(cāng)促,錯(cuò)誤之處敬請(qǐng)諒解,有任何意見(jiàn)可給我留言,愿共同學(xué)習(xí)進(jìn)步。
          posted on 2008-04-19 20:51 Jack.Wang 閱讀(27293) 評(píng)論(13)  編輯  收藏 所屬分類(lèi): 開(kāi)發(fā)技術(shù)

          Feedback

          # re: C#與Java之比較[未登錄](méi) 2008-04-19 21:19 GoKu
          C# 3.0 增加了很多東西,但是也增加了語(yǔ)言復(fù)雜度,有點(diǎn)適得其反的感覺(jué),其實(shí)為了更易看懂,我們不在乎多寫(xiě)一句代碼  回復(fù)  更多評(píng)論
            

          # re: C#與Java之比較[未登錄](méi) 2008-04-19 21:39 Matthew Chen
          在C#中Get和Set不一定成對(duì)出現(xiàn),只要最少包含一個(gè)就夠了。  回復(fù)  更多評(píng)論
            

          # re: C#與Java之比較[未登錄](méi) 2008-04-19 22:02 GoKu
          只讀屬性可以只包含set  回復(fù)  更多評(píng)論
            

          # re: C#與Java之比較[未登錄](méi) 2008-04-19 22:03 GoKu
          是get...  回復(fù)  更多評(píng)論
            

          # re: C#與Java之比較 2008-04-19 23:27 astamei
          http://www.25hoursaday.com/CsharpVsJava.html


          樓主總結(jié)的非常棒,
          我以前看過(guò)一個(gè)e文的比較很全面 (如上鏈接)  回復(fù)  更多評(píng)論
            

          # re: C#與Java之比較 2008-04-21 09:44 mrf
          C#的內(nèi)部類(lèi)沒(méi)有Java的方便!  回復(fù)  更多評(píng)論
            

          # re: C#與Java之比較 2008-04-21 09:53 阿里
          C#跟Java比生來(lái)就具有跟Win 32 Api交互的優(yōu)勢(shì),能跟Windows的dll順暢溝通。  回復(fù)  更多評(píng)論
            

          # re: C#與Java之比較 2008-04-21 09:56 raof01
          "在C#中Get和Set必須成對(duì)出現(xiàn),一種屬性不能只有Get而沒(méi)有Set"——C#可以有單個(gè)Get或Set。  回復(fù)  更多評(píng)論
            

          # re: C#與Java之比較 2008-04-22 03:28 HanLab
          @阿里
          同意,用java native訪(fǎng)問(wèn)動(dòng)態(tài)鏈接庫(kù)函數(shù)有點(diǎn)頭疼。  回復(fù)  更多評(píng)論
            

          # re: C#與Java之比較 2008-04-22 11:57 Jack.Wang
          可以看看我寫(xiě)的那個(gè) JNI 編程,其實(shí)也很不錯(cuò)的!
          java 和 C++ 互調(diào)  回復(fù)  更多評(píng)論
            

          # re: C#與Java之比較 2008-08-06 00:21 whust
          巨大的同感啊,java里調(diào)用系統(tǒng)DLL太困難了@阿里
            回復(fù)  更多評(píng)論
            

          # re: C#與Java之比較 2010-11-16 23:09 純粹路過(guò)的
          @阿里
          因?yàn)閃IN32上的虛擬機(jī)就是C++實(shí)現(xiàn)的,函數(shù)庫(kù)自然是扔DLL了,JDK自帶的NATIVE方法指引著你瞄瞄JDK帶的DLL。  回復(fù)  更多評(píng)論
            

          # re: C#與Java之比較 2014-07-17 10:33 twlkyao
          應(yīng)該是只包含get吧。@GoKu
            回復(fù)  更多評(píng)論
            

          主站蜘蛛池模板: 新晃| 龙海市| 离岛区| 平阳县| 北安市| 乾安县| 寻乌县| 西宁市| 上饶市| 东山县| 六安市| 高唐县| 高密市| 莱西市| 沾化县| 闵行区| 武邑县| 洪洞县| 武定县| 乐安县| 邢台县| 徐水县| 长顺县| 平阴县| 周至县| 来安县| 金堂县| 嘉定区| 华坪县| 广宗县| 灵宝市| 聂拉木县| 金乡县| 汶川县| 阜康市| 新巴尔虎左旗| 赤壁市| 石柱| 玛纳斯县| 富锦市| 灯塔市|