java的學習:內部類

一、什麼是內部類?

內部類就是將一個類定義在另一個類中。

class Outer{

    //內部類
    class Inner{

    }

}

二、內部類的分類

內部類分爲兩類:成員內部類(靜態和非靜態)和局部內部類(方法內,代碼塊內,構造器內)

class Outer {

    //靜態成員內部類
    static class StaticInner {

    }

    //非靜態內部類
    class Inner {

    }


    //方法
    public void method() {
        //局部內部類
        class MethodInner {

        }
    }

    //非靜態代碼塊
    {
        //局部內部類
        class BlockInner {

        }
    }

    //靜態代碼塊
    static{
        //局部內部類
        class BlockInner {

        }
    }

    //構造器
    public Outer() {
        //局部內部類
        class ConstructorInner {

        }
    }
}

2.1 成員內部類

成員內部類作爲外部類的成員,那麼可以調用外部類的結構,可以被static修飾,
可以被4種不同的權限修飾符修飾。

作爲一個類,那麼它必然有着作爲類的一切可以做的,包括了類內可以定義的各種東西(屬性,方法,構造器等對於可以被static修飾的屬性,方法,只能當成員內部類被static修飾時纔有效),可以被final修飾,可以被abstract修飾。

class Outer {

    private String outerName;
    static int outerAge;

    public void outerMethod(){

    }

    class Inner {
        String name;
        final int age=1;
        //static int id=1;  //Inner classes cannot have static declarations

        public Inner(String name) {
            this.name = name;
        }

        public void method(){
            Outer.this.outerMethod();
            //等價於
            outerMethod();//相當於省略了Outer.this.
            Outer.this.outerName="Inner";//可以省略了Outer.this.
            Outer.outerAge=10;

            System.out.println("我是方法");
        }

        public final void finalMethod(){
            System.out.println("我是final方法");
        }

        //Inner classes cannot have static declarations
        //public static void staticMethod(){
        //}
    }

    private class InnerPrivate {

    }

    public class InnerPublic {

    }

    protected class InnerProtected {

    }

    final class InnerFinal {

    }

    static class StaticInner {
        String name;
        static String country="china";
        final int ID=10;

        public StaticInner(String name) {
            this.name = name;
        }

        public void method(){
            System.out.println("我是方法");
        }

        public static void staticMethod(){
            System.out.println("我是靜態方法");
        }

        public final void finalMethod(){
            System.out.println("我是final方法");
        }
    }

}

在類中調用本類中的屬性和方法通過this調用,那麼在內部類中如何調用外部類中的屬性和方法呢?在上例中,Outer.this.outerName="Inner";Outer.this.outerMethod()的形式來調用外部類中的屬性和方法,即外部類名.this.屬性外部類名.this.方法,外部類名.this所代表的含義就是外部類對象的引用。當前外部類屬性和內部類屬性並不重名,那麼如果重名該如何區分呢?

class Outer{
    String name="outer";

    class Inner{
        String name="inner";

        public void method(String name){
            System.out.println(name);//形參
            System.out.println(this.name);//Inner的name屬性
            System.out.println(Outer.this.name);//Outer的name屬性
        }
    }
}

public class Demo{
    public static void main(String[] args) {
        Outer.Inner inner=new Outer().new Inner();
        inner.method("method");
    }
}

輸出:

method
inner
outer
public class Demo {
    public static void main(String[] args) {

        Outer outer=new Outer();
        Outer.Inner inner = outer.new Inner("hh");
        inner.method();

        System.out.println("=======================================");
        Outer.StaticInner staticInner=new Outer.StaticInner("hh");
        staticInner.method();
    }
}

輸出:

我是方法
=======================================
我是方法

上例中,對於非靜態內部類,我們通過使用外部類的對象來創建內部類的對象(如:outer.new Inner("hh");,)來進行實例化內部類。爲什麼要如此?

在擁有外部類對象之前是不可能創建內部類對象的。這是因爲內部類對象會暗暗地連接到建它的外部類對象上。
上述來自《Java編程思想》

對於靜態內部類,我們則不需要外部類的對象了。直接通過new 外部類名.靜態內部類名的方式(如:new Outer.StaticInner("hh");

2.2 局部內部類

在上面我們知道了,局部內部類可以定義在代碼塊,構造器,方法中。
使用局部內部類,不能被public,private,protected修斯。使用局部內部類可以將自身對外部完全的隱藏起來。除了它所在的方法,不能通過任何辦法知道它的存在。局部內部類不僅能訪問外部類結構,還能訪問自身所在方法的局部變量。

class Outer{
    String name="Outer";

    public Comparable getComparable(String name){

        class MyComparable implements Comparable{

            @Override
            public int compareTo(Object o) {
                System.out.println("外部類name:"+Outer.this.name+",內部類name:"+name);
                return 0;
            }
        }

        return new MyComparable();

    }

    public Comparable getComparable2(final String name){
        return new Comparable() {
            @Override
            public int compareTo(Object o) {
                System.out.println("外部類name:"+Outer.this.name+",內部類name:"+name);
                info();
                return 0;
            }
        };

    }

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

public class Demo{
    public static void main(String[] args) {
        Outer outer=new Outer();
        Comparable comparable = outer.getComparable("Inner");
        comparable.compareTo(1);
        System.out.println("==================================");
        Comparable hh = outer.getComparable2("inner");
        hh.compareTo(1);

    }
}

輸出:

外部類name:Outer,內部類name:Inner
==================================
外部類name:Outer,內部類name:inner
info
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章