程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> JAVA編程 >> 關於JAVA >> 周全解讀Java編程中的外部類

周全解讀Java編程中的外部類

編輯:關於JAVA

周全解讀Java編程中的外部類。本站提示廣大學習愛好者:(周全解讀Java編程中的外部類)文章只能為提供參考,不一定能成為您想要的結果。以下是周全解讀Java編程中的外部類正文


Java外部類及其實例化
在 Java 中,許可在一個類(或辦法、語句塊)的外部界說另外一個類,稱為外部類(Inner Class),有時也稱為嵌套類(Nested Class)。

外部類和外層封裝它的類之間存在邏輯上的所屬關系,普通只用在界說它的類或語句塊以內,完成一些沒有通意圖義的功效邏輯,在內部援用它時必需給出完全的稱號。

應用外部類的重要緣由有:
外部類可以拜訪內部類中的數據,包含公有的數據。
外部類可以對統一個包中的其他類隱蔽起來。
當想要界說一個回調函數且不想編寫年夜量代碼時,應用匿名(anonymous)外部類比擬便捷。
削減類的定名抵觸。

請看上面的例子:

public class Outer {
  private int size;
  public class Inner {
    private int counter = 10;
    public void doStuff() {
      size++;
    }
  }
  public static void main(String args[]) {
    Outer outer = new Outer();
    Inner inner = outer.new Inner();
    inner.doStuff();
    System.out.println(outer.size);
    System.out.println(inner.counter);
    // 編譯毛病,內部類不克不及拜訪外部類的變量
    System.out.println(counter);
  }
}

這段代碼界說了一個內部類 Outer,它包括了一個外部類 Inner。將毛病語句正文失落,編譯,會生成兩個 .class 文件:Outer.class 和 Outer$Inner.class。也就是說,外部類會被編譯成自力的字節碼文件。

外部類是一種編譯器景象,與虛擬機有關。編譯器將會把外部類翻譯成用 $ 符號分隔內部類名與外部類名的慣例類文件,而虛擬機則對此一竅不通。

留意:必需先有內部類的對象能力生成外部類的對象,由於外部類須要拜訪內部類中的成員變量,成員變量必需實例化才成心義。

外部類是 Java 1.1 的新增特征,有些法式員以為這是一個值得誇獎的提高,然則外部類的語法很龐雜,嚴重損壞了優越的代碼構造, 違反了Java要比C++加倍簡略的設計理念。

外部類看似增長了—些幽美風趣,實屬沒需要的特征,這是否是也讓Java開端走上了很多說話飽受熬煎的撲滅性途徑呢?本教程其實不盤算就這個成績賜與一個確定的謎底。

Java靜態外部類、匿名外部類、成員式外部類和部分外部類
外部類可所以靜態(static)的,可使用 public、protected 和 private 拜訪掌握符,而內部類只能應用 public,或許默許。
成員式外部類

在內部類外部直接界說(不在辦法外部或代碼塊外部)的類就是成員式外部類,它可以直接應用內部類的一切變量和辦法,即便是 private 的。內部類要想拜訪外部類的成員變量和辦法,則須要經由過程外部類的對象來獲得。

請看上面的代碼:

public class Outer{
  private int size;
  public class Inner {
    public void dostuff() {
      size++;
    }
  }
  public void testTheInner() {
    Inner in = new Inner();
    in.dostuff();
  }
}

成員式外部類好像內部類的一個通俗成員。

成員式外部類可使用各類潤飾符,包含 public、protected、private、static、final 和 abstract,也能夠不寫。

如有 static 潤飾符,就為類級,不然為對象級。類級可以經由過程內部類直接拜訪,對象級須要師長教師成內部的對象後能力拜訪。

非靜態外部類中不克不及聲明任何 static 成員。

外部類可以互相挪用,例如:

class A {
  // B、C 間可以相互挪用
  class B {}
  class C {}
}


成員式外部類的拜訪

外部類的對象以成員變量的方法記載其所依附的外層類對象的援用,因此可以找到該外層類對象並拜訪其成員。該成員變量是體系主動為非 static 的外部類添加的,稱號商定為“outClassName.this”。

1) 應用外部類中界說的非靜態變量和辦法時,要先創立內部類的對象,再由“outObjectName.new”操作符創立外部類的對象,再挪用外部類的辦法,以下所示:

public class Demo{
  public static void main(String[] args) {
    Outer outer = new Outer();
    Outer.Inner inner = outer.new Inner();
    inner.dostuff();
  }
}
class Outer{
  private int size;
  class Inner{
    public void dostuff() {
      size++;
    }
  }
}

2) static 外部類相當於其內部類的 static 成員,它的對象與內部類對象間不存在依附關系,是以可直接創立。示例以下:

public class Demo{
  public static void main(String[] args) {
    Outer.Inner inner = new Outer.Inner();
    inner.dostuff();
  }
}
class Outer{
  private static int size;
  static class Inner {
    public void dostuff() {
      size++;
      System.out.println("size=" + size);
    }
  }
}

運轉成果:

size=1

3) 因為外部類可以直接拜訪其內部類的成份,是以當外部類與其內部類中存在同名屬性或辦法時,也將招致定名抵觸。所以在多層挪用時要指明,以下所示:

public class Outer{
  private int size;
  public class Inner{
    private int size;
    public void dostuff(int size){
      size++; // 部分變量 size;
      this.size; // 外部類的 size
      Outer.this.size++; // 內部類的 size
    }
  }
}

部分外部類

部分外部類(Local class)是界說在代碼塊中的類。它們只在界說它們的代碼塊中是可見的。

部分類有幾個主要特征:

  • 僅在界說了它們的代碼塊中是可見的;
  • 可使用界說它們的代碼塊中的任何部分 final 變量;
  • 部分類弗成所以 static 的,裡邊也不克不及界說 static 成員;
  • 部分類弗成以用 public、private、protected 潤飾,只能應用缺省的;

部分類可所以 abstract 的。

請看上面的代碼:

public class Outer {
  public static final int TOTAL_NUMBER = 5;
  public int id = 123;
  public void func() {
    final int age = 15;
    String str = "http://www.weixueyuan.net";
    class Inner {
      public void innerTest() {
        System.out.println(TOTAL_NUMBER);
        System.out.println(id);
        // System.out.println(str);不正當,只能拜訪當地辦法的final變量
        System.out.println(age);
      }
    }
    new Inner().innerTest();
  }
  public static void main(String[] args) {
    Outer outer = new Outer();
    outer.func();
  }
}

運轉成果:

5
123
15


匿名外部類

匿名外部類是部分外部類的一種特別情勢,也就是沒有變量名指向這個類的實例,並且詳細的類完成會寫在這個外部類外面。

留意:匿名類必需繼續一個父類或完成一個接口。

不應用匿名外部類來完成籠統辦法:

abstract class Person {
  public abstract void 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();
  }
}

運轉成果:

eat something

可以看到,我們用Child繼續了Person類,然後完成了Child的一個實例,將其向上轉型為Person類的援用。然則,假如此處的Child類只應用一次,那末將其編寫為自力的一個類豈不是很費事?

這個時刻就引入了匿名外部類。應用匿名外部類完成:

abstract class Person {
  public abstract void eat();
}
public class Demo {
  public static void main(String[] args){
    
    // 繼續 Person 類
    new Person() {
      public void eat() {
        System.out.println("eat something");
      }
    }.eat();
  }
}


可以看到,匿名類繼續了 Person 類並在年夜括號中完成了籠統類的辦法。

外部類的語法比擬龐雜,現實開辟中也較罕用到,本教程不盤算停止深刻講授,列位讀者也不該該將外部類作為進修Java的重點。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved