Java中的內部類

將一個類的定義放在另一個類的定義內部,成爲內部類。

一、各種形式的內部類及其基本使用

成員內部類:作爲外部類的一個成員存在,與外部類的屬性、方法並列的類。

class Outer{
    private int field = 1;
    private int anotherField = 2;

    //成員內部類
    public class Inner{
        private int field = 10;

        //成員內部類不能有靜態變量與方法,否則出現編譯錯誤:
        //  Inner classes cannot have static declarations
        //private static String staticField = "static";

        public void func(){
            //內部類擁有外部類的所有元素的訪問權,
            //也可以用Outer.this訪問外部類對象
            System.out.println("Inner field: " + field);
            System.out.println("Outer field: " + Outer.this.field);
            System.out.println("Outer anotherField: " + anotherField);
        }
    }
}

public class InnerClassTest {
    public static void main(String[] args) {
        Outer outer = new Outer();
        //需要通過外部類對象創建成員內部類對象
        Outer.Inner inner = outer.new Inner();
        inner.func();
    }
}

 輸出

Inner field: 10
Outer field: 1
Outer anotherField: 2

 

靜態內部類:定義在一個類內部的static的類。

class Outer{
    //靜態內部類不能訪問外部類的非靜態成員
    private int field = 1;
    private static int STATIC_FIELD = 2;

    //靜態內部類
    public static class Inner{
        private int field = 10;
        private static int STATIC_FIELD = 20;

        public void func(){
            System.out.println("Inner field: " + field);
            System.out.println("Inner static field: " + STATIC_FIELD);
            System.out.println("Outer static field: " + Outer.STATIC_FIELD);
        }
    }
}

public class InnerClassTest {
    public static void main(String[] args) {
        //直接使用new創建靜態內部類
        Outer.Inner inner = new Outer.Inner();
        inner.func();
    }
}

 輸出

Inner field: 10
Inner static field: 20
Outer static field: 2

 

 局部內部類:定義在方法或者某個作用域內的類。

interface Interface {
    public void func();
}

class Outer {
    public Interface getInner(int field) {
        //局部內部類
        class Inner implements Interface {
            private int field;

            public Inner(int field) {
                this.field = field;
            }

            @Override
            public void func() {
                System.out.println("Inner: " + field);
            }
        }

        return new Inner(field);
    }

    public void accessInner() {
        //不能在其作用域外訪問局部內部類
        //編譯錯誤:Cannot resolve symbol 'Inner'
        Inner inner = new Inner(1);
    }
}

public class InnerClassTest {
    public static void main(String[] args) {
        Outer outer = new Outer();
        Interface inner = outer.getInner(3);
        inner.func();
    }
}

 

匿名內部類

abstract class AbstractClass {
    protected static int STATIC_FIELD;

    public AbstractClass(int field) {
        this.STATIC_FIELD = field;
    }

    public abstract void func();
}

class Outer {
    public AbstractClass getAnonymousClass(int field) {
        String localField = "localField";

        //創建並返回匿名內部類
        return new AbstractClass(field) {
            @Override
            public void func() {
                System.out.println(STATIC_FIELD);
                //如果在匿名內部類中要使用外部方法的局部變量或者參數變量,
                //則他們必須是final的,下面兩句會產生編譯錯誤:
                //Variable 'field' is accessed from within inner class.
                //Needs to be declared final.
                System.out.println(field);
                System.out.println(localField);
            }
        };
    }
}

public class InnerClassTest {
    public static void main(String[] args) {
        Outer outer = new Outer();
        AbstractClass anonymousClass = outer.getAnonymousClass(2);
        anonymousClass.func();
    }
}

 

二、繼承內部類

class Outer {
    class Inner {
        private int field;

        public Inner(int field) {
            this.field = field;
        }
    }
}

class InheritInner extends Outer.Inner {
    // 繼承成員內部類必須傳入一個外部類對象並顯式地初始化其外
    // 部類對象的引用,否則該類會出現編譯錯誤:
    // No enclosing instance of type 'Outer' is in scope
    public InheritInner(Outer outer, int field) {
        outer.super(field);
    }
}

 

三、多態與內部類

class SuperOuter{
    class Inner{
        public void func(){
            System.out.println("SuperOuter.Inner");
        }
    }
}

class SubOuter extends SuperOuter{
    //內部類不具有多態性,因此這個內部類不會覆蓋父類的同名內部類,
    //兩個內部類是存在於不同命名空間的獨立的類
    class Inner{
        public void func(){
            System.out.println("SubOuter.Inner");
        }
    }
}

public class InnerClassTest {
    public static void main(String[] args) {
        SuperOuter outer = new SubOuter();
        //下面這句會調用SuperOuter.Inner的方法
        outer.new Inner().func();
    }
}

 輸出

SuperOuter.Inner

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章