從C#到Java入門指引之二——類


首發:http://www.eoeandroid.com/thread-233275-1-1.html

eoe社區索引大集合:

http://www.eoeandroid.com/portal.php?mod=topic&topicid=5

android 翻頁卷曲效果(內含源碼)
http://www.eoeandroid.com/thread-232572-1-1.html

Android兩側推出導航菜單的實現
http://www.eoeandroid.com/thread-232567-1-1.html

-----------------帖子正文--------------------

對於一種面向對象語言來說,類是它的核心。這一講,我們就來說說Java的類吧。

忘掉struct,Java只有class
在C#中,我們常常把比較小的數據結構聲明成結構體(struct),這樣生成的對象會分配在堆棧上(注),屬於值類型,傳遞時會復制對象。
在Java中,一切自定義的數據結構都是類(class),它們被分配在堆上,屬於引用類型,傳遞時僅傳遞引用。

我們可以畫一個表:

Java的枚舉和C#的不一樣。C#的枚舉是對整數類型(可以byte、short、int、long等等,char除外)的簡單封裝,而Java的枚舉是一個完整功能的類。

注:如果結構體是某個類的成員變量,那么它還是會被分配在托管堆上。

訪問修飾符
哈哈,還是發現用表格最直觀

可以看出,C#中訪問修飾符的使用細節更繁瑣,但兩者實現的功能基本一致。
其中需要注意的區別是,對於類內部的成員,當缺省訪問修飾符時,C#認為這是私有,而Java認為這是包內可訪問。就這一點,個人感覺像C#這樣把缺省處理成私有更自然一些。

不一樣的關鍵字,不一樣的表示符號
既然是兩種語言嘛,總有些符號和關鍵字的的用法不怎么一樣:

藏起來的virtual
Java的代碼里似乎沒見過virtual吧?
的確是如此,因為Java認定所有方法缺省就是virtual,與基類具有相同簽名的方法缺省就是override
那不想做成虛方法怎么辦?那就加上final關鍵字。

有時候,想override的時候,沒寫對方法的整個簽名,比如返回類型明明是int寫成long了。這時候編譯器不會報錯,而是默默地生成了一個新的方法。
為了杜絕這種狀況,Java
5添加了@Override注解,用來標明重寫的方法。如果這個方法沒有正確重寫基類中的方法,編譯器會報一個錯。

public class SomeCollection{ 
    @Override
    public String toString(){ 
        return super.toString(); 
    } 
}

失落的運算符重載
這個C++都有的特性,Java居然沒有...我能不能吐槽...罷了,不加入運算符重載這個特性,也是有利有弊:
利:Java語法更簡單、易讀。
弊:Java語言的表達能力更弱,靈活性更差。比如C#重載了字符串的==運算符,保證了語義上的一致性;C#中的列表和字典都是可以使用[]的,使代碼變得更直觀,而Java中只有數組才能這么寫。

Java把這個特性砍掉,還是蠻可惜的。像字符串的判等、列表的隨機訪問這些事兒在Java中只是稍微麻煩一些。但如果你嘗試在Java中封裝一個矩陣類,並使用它來實現某個算法,我敢肯定你會為各種小括號的嵌套而抓狂的。

既然不讓重載運算符,那么字符串之間為啥又可以用+連起來?
這個問題問得好!
真相是,你只要把不能加的對象用+連起來,編譯器會自動把它們給toString了,然后放到StringBuilder里連上!

關於Object
在C#中,object是除指針外所有類型的基類;而在Java中,Object是除基本類型外所有類型的基類。
兩者的設計差不多,有這么幾個公開的方法,可以一一對應。除了取得第一個,其他幾個方法都可以被重寫:

類內的初始化塊
剛從C#轉過來的同學可能會被類內部“莫名其妙”出現的大括號給弄糊塗了,“這段代碼時干神馬的呢”

public class SomeCollection{ 
    private int[] mArray; 
      
    { 
        mArray = new int[10]; 
        for(int i=0; i<10; i++){ 
            mArray[ i] = i; 
        } 
    } 
      
    public SomeCollection{ 
    } 
}

那是Java的初始化塊,它會在構造方法執行之前執行。
如果有一個字段的初始化不能在=右邊用一句話搞定,並且所有構造方法都需要用的話,可以考慮提取出來弄成初始化塊。

另外,針對靜態字段也有對應的靜態初始化塊,在前面的大括號前加上“static”就行啦。

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM