java中的內部類

yzuu0391 8年前發布 | 5K 次閱讀 Java 面向對象編程 Java開發

一.什么是內部類?

答:內部類( Inner Class )就是定義在另外一個類里面的類。與之對應,包含內部類的類被稱為外部類

二.為什么要使用內部類?

答:1.內部類可以提供更好的封裝,將一個類隱藏在另一個類內,不允許同一個包中其他類訪問這個內部類

2.內部類的方法可以直接訪問外部類的所有數據,包括私有的數據

3.內部類所實現的功能使用外部類同樣可以實現,只是有時使用內部類更方便

三.內部類有幾種?

答:1.成員內部類

2.靜態內部類

3.方法內部類

4.匿名內部類

四.介紹四種內部類

(1)成員內部類:

1.Inner 類定義在 Outer 類的內部,相當于 Outer 類的一個成員變量的位置,Inner 類可以使用任意訪問控制符,如 public 、 protected 、 private 等

2.Inner 類中定義的 test() 方法可以直接訪問 Outer 類中的數據,而不受訪問控制符的影響,如直接訪問 Outer 類中的私有屬性a

3.定義了成員內部類后,必須使用外部類對象來創建內部類對象,而不能直接去 new 一個內部類對象,即:內部類 對象名 = 外部類對象.new 內部類( );

4.編譯之后,會出現兩個.class文件。HelloWorld.class 和 HelloWorld$Inner.class

5.外部類是不能直接使用內部類的成員和方法,可先創建內部類的對象,然后通過內部類的對象來訪問其成員變量和方法。

6.如果外部類和內部類具有相同的成員變量或方法,內部類默認訪問自己的成員變量或方法,如果要訪問外部類的成員變量,可以使用 this 關鍵字

//外部類HelloWorld
public class HelloWorld{

//外部類的私有屬性name
private String name = "study";

//外部類的成員屬性
int age = 20;

//成員內部類Inner
public class Inner {
    String name = "學習";
    //內部類中的方法
    public void show() { 

                         //訪問外部類中的同名變量需要使用this變量去訪問 System.out.println("外部類中的name:" + HelloWorld.this.name); System.out.println("內部類中的name:" +name); System.out.println("外部類中的age:" + age); } }

//測試成員內部類
public static void main(String[] args) {

    //創建外部類的對象
    HelloWorld o = new HelloWorld (); 

    //創建內部類的對象,定義了成員內部類后,必須使用外部類對象來創建內部類對象
    Inner inn = o.new Inner();

    //調用內部類對象的show方法
    inn.show();
}

} </code></pre>

運行結果:

外部類中的name:study
內部類中的name:學習
外部類中的age:20

(2)靜態內部類

1.靜態內部類不能直接訪問外部類的非靜態成員,但可以通過  new 外部類().成員 的方式訪問

int wo=new HelloWorld().shei;

2.如果外部類的靜態成員與內部類的成員名稱相同,可通過“類名.靜態成員”訪問外部類的靜態成員;如果外部類的靜態成員與內部類的成員名稱不相同,則可通過“成員名”直接調用外部類的靜態成員

3.創建靜態內部類的對象時,不需要外部類的對象,可以直接創建 內部類 對象名= new 內部類();

//外部類
public class HelloWorld {

// 外部類中的靜態變量score
private static int score = 84;
private int shei=1;
// 創建靜態內部類
public static class SInner {
    // 內部類中的變量score
    int score = 91;

    public void show() {

                            //訪問同名靜態變量類名.靜態變量 System.out.println("訪問外部類中的score:" + HelloWorld.score); System.out.println("訪問內部類中的score:" + score);                             //不能直接訪問非靜態變量 int wo=new HelloWorld().shei; } }

// 測試靜態內部類
public static void main(String[] args) {
    // 直接創建內部類的對象,不用 外部類對象.new SInner();
    SInner si=new SInner();

    // 調用show方法
    si.show();
}

} </code></pre>

運行結果:

訪問外部類中的score:84
訪問內部類中的score:91

</code></pre>

(3)方法內部類

1.方法內部類就是內部類定義在外部類的方法中,方法內部類只在該方法的內部可見,即只在該方法內可以使用。

2.由于方法內部類不能在外部類的方法以外的地方使用,因此方法內部類不能使用訪問控制符和 static 修飾符

//外部類
public class HelloWorld {

private String name = "學習";

// 外部類中的show方法
public void show() { 
    // 定義方法內部類
    class MInnder {
        int score = 83;
        public int getScore() {
            return score + 10;
        }
    }

    // 創建方法內部類的對象

    MInner inner=new MInner();
    // 調用內部類的方法

    int newScore=inner.getScore();
    System.out.println("姓名:" + name + "\n加分后的成績:" + newScore);
}

// 測試方法內部類
public static void main(String[] args) {

    // 創建外部類的對象
    HelloWorld mo=new HelloWorld();

    // 調用外部類的方法
    mo.show();
}

} </code></pre>

運行結果:

姓名:學習
加分后的成績:93

(4)匿名內部類

1.匿名內部類也就是沒有名字的內部類

2.正因為沒有名字,所以匿名內部類只能使用一次,它通常用來簡化代碼編寫

3.但使用匿名內部類還有個前提條件:必須繼承一個父類或實現一個接口

實例1:不使用匿名內部類來實現抽象方法

//抽象類
abstract class Person {
    public abstract void eat();
}

//繼承并實現抽象方法eat class Child extends Person { public void eat() { System.out.println("eat something"); } }

public class Demo { public static void main(String[] args) { Person p = new Child(); p.eat(); } } </code></pre>

運行結果:eat something

可以看到,我們用Child繼承了Person類,然后實現了Child的一個實例,將其向上轉型為Person類的引用

但是,如果此處的Child類只使用一次,那么將其編寫為獨立的一個類豈不是很麻煩?

這個時候就引入了匿名內部類

實例2:匿名內部類的基本實現

abstract class Person {
    public abstract void eat();
}

public class Demo { public static void main(String[] args) { //抽象類的方法直接在大括號中實現
Person p = new Person() { public void eat() { System.out.println("eat something"); } }; p.eat(); } } </code></pre>

運行結果:eat something

可以看到,我們直接將抽象類Person中的方法在大括號中實現了

這樣便可以省略一個類的書寫

并且,匿名內部類還能用于接口上

實例3:在接口上使用匿名內部類

interface Person {
    public void eat();
}

public class Demo { public static void main(String[] args) { Person p = new Person() { public void eat() { System.out.println("eat something"); } }; p.eat(); } } </code></pre>

運行結果:eat something

由上面的例子可以看出,只要一個類是抽象的或是一個接口,那么其子類中的方法都可以使用匿名內部類來實現

最常用的情況就是在多線程的實現上,因為要實現多線程必須繼承Thread類或是繼承Runnable接口

實例4:Thread類的匿名內部類實現

public class Demo {
    public static void main(String[] args) {
        Thread t = new Thread() {
            public void run() {
                for (int i = 1; i <= 5; i++) {
                    System.out.print(i + " ");
                }
            }
        };
        t.start();
    }
}

運行結果:1 2 3 4 5

實例5:Runnable接口的匿名內部類實現

    
public class Demo {
    public static void main(String[] args) {
        Runnable r = new Runnable() {
            public void run() {
                for (int i = 1; i <= 5; i++) {
                    System.out.print(i + " ");
                }
            }
        };
        Thread t = new Thread(r);
        t.start();
    }
}

運行結果:1 2 3 4 5

 

來自:http://www.cnblogs.com/jijiji/p/5934080.html

 

 本文由用戶 yzuu0391 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!