1. 程式人生 > >內部類及匿名內部類的詳細描述

內部類及匿名內部類的詳細描述

    內部類(Inner Class)

內部類的定義:

         在Java中,允許在一個類的內部定義類,這樣的類稱作內部類也叫做巢狀類, 這個內部類所在的類稱作外部類。

內部類的建立:

語法:  外部類名.內部類名 變數名=new 外部類名().new 內部類名();

舉例:  假設A是外部類,B是內部類

        A.B b=new A().new B();

建立內部類物件時應注意:

1.在外部類的內部可以直接使用inner s=new inner();(因為外部類知道inner是哪個類,所以可以生成物件。)

2.在外部類的外部,要生成(new)一個內部類物件,需要首先建立一個外部類物件(外部類可用),然後在生成一個內部類物件。

內部類的表現形式:

1.靜態內部類

2.成員內部類

3.方法內部類

4.匿名內部類

內部類的共性:

1.內部類仍然是一個獨立的類,在編譯之後會內部類會被編譯成獨立的.class檔案,但是前面冠以外部類的類命和$符號。

2.內部類不能用普通的方式訪問。內部類是外部類的一個成員,因此內部類可以自由地訪問外部類的成員變數,無論是否是private的。

內部類的優點:

1.內部類成員可以直接訪問外部類的成員(包括私有成員)

2.比類具有更好的封裝性

基本形式:

public class Outer1 {

    public class Inner{  

    }  

}

例子:

1.public class Outer {

private int num=4; //定義成員變數

public void test(){

Inner inner =new Inner();

inner.show();

}

//下面的程式碼定義了一個成員內部類

class Inner{

void show(){

//在成員內部類的方法中訪問外部類的成員變數

System.out.println("num="+num);

}

}

}

public class Example {

public static void main(String[] args){

Outer.Inner inner =new Outer().new Inner();    //建立內部類物件

inner.show();             //呼叫test()方法

}

}

2.public class Myclass {

public Myclass() {  

        System.out.println("產生MyClass");  

    }  

    class M {  

        public M() {  

            System.out.println("產生M");  

        }  

    }  

    public static void main(String[] args) {  

        Myclass my = new Myclass();  

        // 內部類相當於外部類的屬性,內部類物件的產生要依賴於外部類物件,只要是屬性可以有的修飾符都可以修飾內部類。  

        // 內部類在編譯時同樣會產生class檔案。命名為:外部類名$內部類名.class  

        Myclass.M m = my.new M();  

    }  

}

匿名內部類(Anonymous Inner Class)

匿名內部類的定義:

沒有名字的內部類。表面上看起來那是它的名字,實際上不是它的名字。

使用匿名內部類的前提:

必須繼承父類或實現一個介面

匿名內部類的分類:

1.繼承式的匿名內部類

2.介面式的匿名內部類

3.引數式的匿名內部類

特點:

匿名內部類一定是跟在new的後面,用其隱含實現一個介面或一個類,沒有類名,根據多型,我們使用其父類名。因為匿名內部類屬於區域性類,所以區域性類的所有限制對其生效。匿名內部類是唯一一種無構造方法的類。匿名內部類在編譯時,系統自動起名Out$1.class。如果一個物件編譯時的型別是介面,那麼其執行的型別為實現這個介面的類。

注意點:

1.不能有構造方法

2.不能定義任何靜態成員、方法或類

3.不能是public,protected,private,static。   

4.只能建立匿名內部類的一個例項。

匿名內部類的優點:

可以使命名變得簡潔

使程式碼更加緊湊,簡潔,封裝性比內部類更優

一個類用於繼承其他類或是實現介面,無需增加其他的方法,只是對繼承方法實現   覆蓋。

匿名內部類的缺點:

可讀性差

例子:

1.public class Dog {               //建立一個Dog

 static abstract class Ball {           //建立一個抽象類

        abstract String getName();          //建立一個抽象方法,抽象方法必須用abstract來修飾

    }  

    void play(Ball b){  

        System.out.println(b.getName());  

    }  

    public static void main(String[] args){  

        Dog dog = new Dog();  

        dog.play(new Ball(){      //匿名內部類實現抽象方法getName();

            @Override  

            String getName() {  

                return "qiu qiu";  

            }});  

    }  

}

(2).

    public interface Product {

public double getPrice();

public String getName();

}

public class TestAnonymous {

public void test(Product p){

System.out.println("我購買了一個"+p.getName()+",花掉了"+p.getPrice());

}

public static void main(String[] args){

TestAnonymous ta=new TestAnonymous();

//呼叫test方法,需要傳入一個Product引數,此處傳入其匿名,實現類的例項

ta.test(new Product(){      

public double getPrice(){

return 40;

}

public String getName(){

return "水晶球";

}

});

}

}

//以上的匿名內部類相當於

/*

 class AnonymousProduct implements Product             //implements是實現介面的關鍵字

 {

  public double getPrice(){

  return 40;

  }

  public String getName(){

  return "水晶球";

  }

 }

 ta.test(new AnonymousProduct());

*/