java內部類,區域性內部類,靜態內部類,匿名內部類

大資料-劉耀文發表於2018-09-07

內部類:定義在A類內部的B類就是內部類,B類在A類的地位與其它的成員相同,大家可以互相呼叫

package com.qianfeng.test;
/*
* 內部類:定義在A類內部的B類就是內部類,B類在A類的地位與其它的成員相同,大家可以互相呼叫
*/
public class Demo4 {

public static void main(String[] args) {

    //呼叫內部類的方法
    //第一種方式:藉助外部類的方法呼叫,實現內部類物件的呼叫
    Outer outer = new Outer();
    outer.show();

    //第二種方式:直接實現內部類
    //建立內部類物件的方式:外部類的物件.new 內部類的構造方法
    //Outer.Inner:獲取內部類的方式
    Outer.Inner inner = outer.new Inner();
    inner.play();
}

}

class Outer{

int age;
class Inner{//內部類
    int height;
    public void play(){
        System.out.println("Inner-play");
    }
}


public void show(){
    //藉助外部類的方法呼叫,實現內部類物件的呼叫
    Inner inner = new Inner();
    inner.play();
    System.out.println("show");
}

}

//例項:通過內部類可以讓java間接實現多繼承
class A{

}

class B{

}

class X extends A{
class Y extends B{

}

}


區域性內部類:定義在一個類方法中的類

package com.qianfeng.test;

import com.qianfeng.test.Outer.Inner;

/*
* 區域性內部類:定義在一個類方法中的類
*
* 作用範圍:從定義區域性內部類開始到show方法結束
*
* 作用:對於當前區域性內部類所在的方法,相當於將他的一部分功能物件導向了.形成了區域性內部類,這樣即保證了程式碼的私有化,又
* 對程式碼進行了重新的整理,增加了程式碼的可讀性,可操作性,簡化程式碼,增加了複用性.
*
* 瞭解:
* show方法中與區域性內部類地位等同的區域性變數的使用規則
*
*
* * 瞭解:區域性內部類所在的方法中區域性變數的使用.
* 區域性變數的作用域:定義變數開始到函式結束
* final:被final修飾的變數會被放在常量區,而常量區的值存在的時間要大於區域性變數所在的方法,相當於從原來的基礎上擴大了作用域
*
* 原理:
* 當方法中同時存在區域性內部類與成員變數時,成員變數的使用範圍就會從原來的基礎上進行擴大.
* 原因:在當前的情況下,程式會預設讓final去修飾height.所以當區域性變數所在的方法結束的時候,變數沒有被釋放,儲存的值還在.
*
* 關於變數前面的final:
* 前提:變數必須與區域性內部類同時存在.
* 在jdk1.7之前要想保住區域性變數的值,要手動新增final
* 在jdk1.7之後,java的內部機制已經在變數的前面預設新增了final
*/
public class Demo5 {
public static void main(String[] args) {

}

}

class Outer1{
int age;

public void show(){
    int weight;
    class Inner{//區域性內部類
        int height;
        public void play(){
            System.out.println("Inner-play");
        }
    }

    //在外部類的方法中呼叫內部類
    Inner inner = new Inner();
    inner.play();
    System.out.println("Outer1-show");
}

}

//例項:要求:將兩個小功能變成play的私有功能
//我們通過區域性內部類實現了功能的私有化,並對方法內部的程式碼進行了整理,增強了程式碼的可讀性和可操作性.
class Test{

public void play(){
    //因為方法的定義之間是不能巢狀的,所以必須通過區域性內部類實現.

// public void gongneng1(){
// System.out.println(“gongneng1”);
// }
//
// public void gongneng2(){
// System.out.println(“gongneng2”);
// }
//使用區域性內部類
class Inner{
public void gongneng1(){
System.out.println(“gongneng1”);
}

        public void gongneng2(){
            System.out.println("gongneng2");
        }
    }

    Inner inner = new Inner();
    inner.gongneng1();
    inner.gongneng2();
}

public void show(){
    //無法調到.因為:兩個方法是play方法的區域性內部類方法,只對play可見

// gongneng1();
// gongneng2();
}
}


區域性內部類小demo。tostring的值可以取到7,所以說明區域性變數的值被存住了。
package com.qianfeng.test;

public class Demo6 {
public static void main(String[] args) {
Outer2 outer2 = new Outer2();
outer2.show();
outer2.test();
}
}

//模擬jdk1.7之前區域性變數之前會加final的情況–區域性變數的值會被存住
class Outer2{
int age;

Object object = null;
public void show(){
    int weight = 7;
    class Inner{//區域性內部類
        int height;
        public void play(){
            System.out.println("Inner-play");
        }

        @Override
        public String toString() {
            // TODO Auto-generated method stub
            return "tostring"+weight;
        }
    }

    //在外部類的方法中呼叫內部類
    object = new Inner();  //多型
}

public void test(){
    System.out.println(object.toString());
    System.out.println("test");
}

}


靜態內部類

package com.qianfeng.test;
/*
* 瞭解:
* 靜態內部類:
*
* 注意點:
* 1.靜態內部類中可以沒有靜態成員
* 2.有靜態成員的一定是靜態內部類
*
*/
public class Demo7 {

public static void main(String[] args) {

    //工作:
    //靜態的物件
    //注意:要保證內部類本身是靜態的
    //構成:new 外部類.內部類的構造方法
    Outer3.Inner inner = new Outer3.Inner();

    //呼叫方法
    inner.play();
    inner.show();
    Outer3.Inner.show();


}

}

class Outer3{
static int age;
static class Inner{//靜態內部類

    //非靜態的方法
    public void play(){
        System.out.println("非靜態方法-play");
    }

    //靜態的方法
    public static void show(){
        System.out.println("靜態方法-show");
    }

}

}


匿名內部類(物件):定義在一個類方法中的匿名子類物件,屬於區域性內部類

package com.qianfeng.test;
/*
* 等級:中
* 匿名內部類(物件):定義在一個類方法中的匿名子類物件,屬於區域性內部類
*1. 匿名子類物件
*2. 匿名的內部類物件
*
* 建立匿名內部類物件注意點:1.匿名內部類物件必須有父類或者父介面
*
匿名內部類物件的作用:
* 1.當只用到當前子類的一個例項物件的時候,定義好馬上使用
* 2.當不好起名字的時候
* 3.可以更好的定義執行時的回撥(知道即可)
*
* 內部類的作用:
* 1.間接實現了多繼承
* 2.方便定義
* 3.只有外部類可以訪問建立的內部類的屬性和方法,包括私有方法
* 4.同一個包中其他的類不可見,有了很好的封裝性
*
*/
public class Demo8 {
public static void main(String[] args) {
// //研究匿名子類物件
// //建立匿名物件,完成方法的呼叫
// new Tests().testsMethod();
//
// //建立匿名子類物件
// //第一種方式
// //使用已有的子類生成匿名子類物件
// //使用場景:現成的子類可以使用多次,當相同的功能需要呼叫多次的時候.
// new SubTests().testsMethod();
//
// //第二種方式
// //直接建立沒有名字的Tests類的匿名子類物件
// //構成:new + 父類的類名/父介面的名字+()+{匿名子類的執行體};
// //使用場景:只能使用一次,使用完立即釋放,適合於每次都需要不同的功能
// new Tests(){
// @Override
// public void testsMethod() {
// System.out.println(“沒有名字-testsMethod”);
// }
// //自己的方法
// public void play(){
// System.out.println(“沒有名字-play”);
// }
// }.play();

    //研究匿名內部類物件
    Out out = new Out();
    out.show();
    out.testCanshu1();
    out.testCanshu2();
    Tests tests1 = out.testFanhuizhi1();
    System.out.println(tests1);
    Tests tests2 = out.testFanhuizhi2();//多型
    tests2.testsMethod();
    //tests2.play();//無法呼叫,play是子類特有的方法
    System.out.println(tests2);
}

}

//建立一個類研究匿名子類物件
class Tests{
public void testsMethod(){
System.out.println(“Tests-testsMethod”);
}
}

class SubTests extends Tests{
@Override
public void testsMethod() {
System.out.println(“SubTests-testsMethod”);
}
}

//研究匿名內部類
class Out{
public void show(){
new Tests(){//匿名內部類
@Override
public void testsMethod() {
System.out.println(“沒有名字-testsMethod”);
}
//自己的方法
public void play(){
System.out.println(“沒有名字-play”);
}
}.play();
}

//普通的匿名物件充當引數
public void testCanshu1(){
    System.out.println(new Tests());
}

//使用匿名的子類物件充當引數
public void testCanshu2(){
    System.out.println(

        new Tests(){
            @Override
            public void testsMethod() {
                System.out.println("沒有名字-testsMethod");
            }
            //自己的方法
            public void play(){
                System.out.println("沒有名字-play");
            }

            @Override
            public String toString() {
                return "冰冰真漂亮!";
            }
        }
    );
}

//普通的匿名物件做返回值
public Tests testFanhuizhi1(){
    return new Tests();
}

//使用匿名內部類充當返回值
public Tests testFanhuizhi2(){
    return new Tests(){
        @Override
        public void testsMethod() {
            System.out.println("沒有名字-testsMethod");
        }
        //自己的方法
        public void play(){
            System.out.println("沒有名字-play");
        }

        @Override
        public String toString() {
            return "冰冰真漂亮!";
        }
    };
}

//練習:建立介面的匿名內部類

}

相關文章