Java 學習筆記(8)——匿名對象與內部類

通常在編寫代碼時可能會遇到這樣的場景——在某些時候,我須要定義並某個類,可是隻會使用這一次,或者是某個類對象只會使用一次,爲它們專門取名可能會顯的很麻煩。爲了應對這種狀況,Java中容許使用匿名對象和匿名內部類的方式來解決這個矛盾
java

匿名對象

普通的類對象在使用時會定義一個類類型的變量,用來保存new出來的類所在的地址。而匿名類取消掉了這個變量,這個地址由編譯器來處理,而且在new出來以後,它佔用的內存會有JVM自動回收掉。後續沒法再使用了。
例如函數

public class Student{
    public void classBegin(){
        System.out.println("good morning teacher!");
    }
}

new Student().classBegin();

匿名對象最經常使用的方式是做爲函數的參數,好比上述的打印語句 "good morning teacher!" 它就是一個匿名對象,因爲字符串是以對象的形式存儲的,因此這裏實際上就是一個沒有使用對象引用的匿名對象。this

固然也能夠將匿名對象做爲函數的返回值。設計

內部類

內部類的種類:成員內部類、靜態內部類、局部內部類、匿名內部類code

成員內部類

java中容許在一個類中定義另外一個類。例如對象

public class Car{
    public class Engine{
        
    }
}

上述例子在Car這個類中定義了一個Engine類,那麼Car就是外部類,而Engine就是內部類。接口

使用內部類須要注意:外部類是包含內部類的,因此內部類能夠看到外部類的全部屬性和方法,包括private方法。可是反過來則不行;內存

使用內部類主要有兩種方式:字符串

  • 在外部類中使用內部類的成員(間接使用)。這種方法通常是在外部類的方法中建立內部類的對象,並調用對象的方法
  • 直接使用:根據上面的定義,能夠這樣使用 `Car.Engine eng = new Car().new Engine()

好比下面的例子編譯器

public class Car{
    public class Engine{
        public void start(){
            System.out.println("引擎啓動");
        }
    }

    //間接調用
    public void start(){
        System.out.println("打火");
        new Engine().start();
    }

    public static void main(String[] args){
        new Car().start();

        //直接調用
        Car.Engine engine = new Car().new Engine();
        engine.start(); 
    }
}

當外部類和內部類的成員發生命名衝突的時候在內部類中可使用 外部類.this.成員變量 來訪問外部類的成員
好比說

public class Car{
    public String type = "奧迪";
    public class Engine{
        public String type = "奧迪引擎";
        public void start(){
            System.out.println("引擎啓動");
        }
        
        public void carType(){
            System.out.println(Car.this.type);
        }
    }

    //間接調用
    public void start(){
        System.out.println("打火");
        new Engine().start();
    }

    public static void main(String[] args){
        Car car = new Car();
        //直接調用
        Car.Engine engine = new Car().new Engine();
        engine.start();
        engine.carType();
        
    }
}

局部內部類

內部類不光能夠直接定義在外部類中做爲成員內部類,也能夠定義在方法中,做爲局部內部類

局部內部類也叫區域內嵌類,局部內部類與成員內部類相似,不過,區域內嵌類是定義在一個方法中的內嵌類

主要特定有:

  • 局部內部類只能在對應方法中訪問,在方法外無效
  • 不能使用private,protected,public修飾符。
  • 不能包含靜態成員
  • 局部內部類若是想要訪問方法中的局部變量時,局部變量必須是常量。由於局部變量時分配在棧中,而局部內部類是分配在堆中的,有可能出現這樣的狀況,外部類的方法執行完了,內存被回收了,可是局部內部類可能還在,因此在訪問局部變量時,作了一個拷貝將局部變量拷貝到局部內部類所在的堆中。爲了保證數據的完整性,因此這裏被拷貝的變量不容許再作修改。
public class carShow(){
    public void showCar(){
        final float price = 10000000f;
        final String type = "奔馳";

        class Car(){
            public void show(){
                System.out.println("這個車是" + type + ",售價:" + price);
            }
        }
    }
}

靜態內部類

內部類若是使用static聲明,則此內部類就稱爲靜態內部類。它能夠經過 外部類 . 內部類 的方式來訪問。因爲靜態內部類是與對象無關的,在使用靜態類的成員時是不須要建立對象的。因此若是想要在靜態內部類中來訪問外部類的成員變量,必須經過外部類的對象實例來訪問。

public class Company {
    String companyNam;
    static String country;
    static class Clear{
        String name;
        public Clear() {
        }
        
        public Clear(String name) {
            super();
            this.name = name;
        }

        public void work(String name){
            String na = new Company().companyNam="聯想";
            country="中國";
            System.out.println(name+"爲"+na+"打掃衛生,該公司屬於"+country);
        }
    }
}

匿名內部類

若是一個內部類在整個操做中只使用一次的話,就能夠定義爲匿名內部類。匿名內部類也就是沒有名字的內部類,這是java爲了方便咱們編寫程序而設計的一個機制,由於有時候有的內部類只須要建立一個它的對象就能夠了,之後再不會用到這個類,這時候使用匿名內部類就比較合適。

匿名內部類,通常都伴隨着接口一塊兒使用好比

public interface USB{
    public abstract void open();
    public abstract void close();
}

public class Demo{
    public static void main(String[] args){
        USB usb = new USB(){
            public void open(){}
            public void close(){}
        }

        usb.open();
        usb.close();

        //使用匿名內部類的匿名對象的方式
        USB usb = new USB(){
            public void open(){}
            public void close(){}
        }.open();
    }
}

在Demo這個類的main方法中建立了一個局部的內部類,這個內部類沒有名字,也就是建立了一個匿名內部類。

相關文章
相關標籤/搜索