從C#到Java入門指引之三——內部類

來源:互聯網
上載者:User

C#和Java對static關鍵字的理解有很大分歧,主要就是在內部類上。此外,由於Java沒有類似委託這種資料結構,內部類還要擔當封裝方法和響應事件這樣的重要責任。

從C#到Java入門指引之一——基本類型和字串
從C#到Java入門指引之二——類
從C#到Java入門指引之三——內部類

截然不同的內部類

與C#不一樣,Java不允許外部類使用static關鍵字修飾。那麼我們來看看static關鍵字修飾內部類的一個例子(來自《細說Java》)

public class Circle {    private static int radius;    public static class Center{        // 靜態內部類也可聲明靜態成員        private static Center defaultCenter;        static {            defaultCenter = new Center(10, 10);            // 訪問外部類的私人成員            System.out.println(radius);        }         public int x, y;        public Center(int x, int y){            this.x = x;            this.y = y;        }    }} public class Main{    public static void main(String[] args){        // 靜態內部類可以不依賴外部來執行個體的存在而存在        Circle.Center center = new Circle.Center(15, 20);    }}

習慣C#的同學只怕又會覺得納悶,明明這個內部類都static了,為啥還有構造方法?!
這是兩種語言對static的不同解讀造成的:
在C#中,static修飾內部類,表示這是個不能夠執行個體化的靜態類;而在Java中,這表示這個內部類可以不依賴於外部類的執行個體而執行個體化。

所以,Java中加了static的內部類相當於C#中普通的內部類。
那麼,沒加static修飾的內部類,又表示什麼呢?自然是依賴於外部類的執行個體才能執行個體化的內部類嘛!

public class Circle {    private int radius;    public class Center{        // 普通內部類也可聲明靜態成員        //private static Center defaultCenter;         // 但是可以含有靜態常量        private static final int FINAL_STATIC = 10;         public int x, y;        private int radius;        public Center(int x, int y){            this.x = x;            this.y = y;            radius = 3; // 訪問內部類的成員            this.radius = 3; // this指向內部類            Circle.this.radius = 3; // Circle.this指向外部類        }    }} public class Main{    public static void main(String[] args){        // 普通內部類必須依賴外部類的執行個體        //Circle.Center center = new Circle.Center(15, 20);         // 必須先建立外部類的執行個體        Circle circle = new Circle();        Circle.Center center = circle.new Center(15, 20);    }}

看到建立內部類執行個體的那行代碼,是否覺得很彆扭?
沒錯,而且如果又涉及到繼承的話,比如繼承某個類的內部類,那就更加繁瑣了。所以我的建議是,非static的內部類,能不用就不用。

方法內聲明的局部類

普通內部類可以在語句塊(比如方法)內聲明,那就是局部類。
局部類只在當前語句塊內可訪問。
局部類可以訪問語句塊中的局部變數(但必須用final修飾),以及外部類中的成員。

更為常用的匿名類

如果局部類只是用一次,就可以聲明為匿名類。例子同樣來自《細說Java》:

interface Center{} public class Circle {    public Center getCenter(final int pointX, final int pointY){        return new Center(){            public int x, y;            {                x = pointX;                y = pointY;            }        };    }} public class Main{    public static void main(String[] args){        Circle circle = new Circle();        Center center = circle.getCenter(10, 15);    }}

匿名類不能聲明構造方法,所以只能用初始化塊的方式對成員初始化。
匿名類也不是new後面的那個類型:如果new後面是一個類,那麼匿名類的類型是這個類的子類;如果new後面是一個介面,那麼匿名類的類型是這個介面的一個實現。

比如我們常常會給Activity添加一個Handler,以處理各種訊息。每個Activity的Activity各不相同,所以也就沒有重用的必要,用匿名類即可:

private Handler mHandler = new Handler() {    @Override    public void handleMessage(Message msg) {        //...    }};

匿名類用於封裝方法

許多時候,我們需要把方法當成一個變數處理,傳給另一個方法。C/C++可以用函數指標,C#可以用委託。Java沒有比較直觀的方式,但一般可以這麼做:
1.建立介面IFunc,裡面放一個方法的原型,比如void func();
2.建立實現了IFunc的類FuncClass,實現其中的func方法;
3.建立類FuncClass的對象funcObject,傳遞給別的方法。

很麻煩是不,好在有匿名類,可以將建立類和建立對象合成一步。比如,想要把一段代碼放到新線程去跑,就得把代碼塞到很麻煩是不,好在有匿名類,可以將建立類和建立對象合成一步。
比如,想要把一段代碼放到新線程去跑,就需要建立Runnable介面的實現,把代碼塞到run方法,傳給Thread的構造方法:

Thread thread = new Thread(new Runnable() {    @Override    public void run() {        //...    }});thread.start();

註:實際使用時,只需要直接重寫Thread的run方法,這麼寫其實是繞了彎路。

實現那個方法人們會把需要傳遞的方法放在一個類裡面,然後用這個類建立一個對象,通過傳遞這個對象來實現傳遞方法。這時候,匿名類就可以大顯身手了。

匿名類與事件響應機制

許多時候,我們需要把方法當成一個變數處理,傳給另一個方法。C/C++可以用函數指標,C#可以用委託,但Java沒有比較直觀的方式。通常,在Java代碼中,人們會把需要傳遞的方法放在一個類裡面,然後用這個類建立一個對象,通過傳遞這個對象來實現傳遞方法。這時候,匿名類就可以大顯身手了。

最簡單的例子,響應按鈕的點擊事件:

mButton.setOnClickListener(new View.OnClickListener(){    @Override    public void onClick(View view){        //...    }}

預設為靜態內部介面

聲明在類內部的介面,即為內部介面。
內部介面預設就是靜態————這個也容易理解,既然是介面,難道還要依賴於外部類的執行個體而存在麼。

 

 

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.