Java內部類型別


可以在類中的任何位置定義內部類,並在其中編寫Java語句。有三種型別的內部類。 內部類的型別取決於位置和宣告的方式。

  • 成員內部類
  • 區域性內部類
  • 匿名內部類

成員內部類

成員內部類在類中宣告的方式與宣告成員欄位或成員方法相同。它可以宣告為publicprivateprotectedpackage-level。成員內部類的範例可以僅存在於其封閉類的範例內。

以下程式碼建立了一個成員內部類。

class Car {
  private int year;

  // A member inner class named Tire public
  class Tire {
    private double radius;
    public Tire(double radius) {
      this.radius = radius;
    }
    public double getRadius() {
      return radius;
    }
  } // Member inner class declaration ends here

  // A constructor for the Car class
  public Car(int year) {
    this.year = year;
  }
  public int getYear() {
    return year;
  }
}

區域性內在類

一個區域性內部類在塊中宣告。 其範圍僅限於宣告它的塊。由於其範圍限於其封閉塊,因此其宣告不能使用任何存取修飾符,例如publicprivateprotected
通常,在方法內定義區域性內部類。 但是,它也可以在靜態初始化器,非靜態初始化器和構造器中定義。下面的程式碼顯示了一個區域性內部類的例子。

import java.util.ArrayList;
import java.util.Iterator;

public class Main {
  public static void main(String[] args) {
    StringList tl = new StringList();
    tl.addTitle("A");
    tl.addTitle("B");

    Iterator iterator = tl.titleIterator();
    while (iterator.hasNext()) {
      System.out.println(iterator.next());
    }
  }
}
class StringList {
  private ArrayList<String> titleList = new ArrayList<>();

  public void addTitle(String title) {
    titleList.add(title);
  }

  public void removeTitle(String title) {
    titleList.remove(title);
  }

  public Iterator<String> titleIterator() {
    // A local inner class - TitleIterator
    class TitleIterator implements Iterator<String> {
      int count = 0;
      @Override
      public boolean hasNext() {
        return (count < titleList.size());
      }

      @Override
      public String next() {
        return titleList.get(count++);
      }
    }

    TitleIterator titleIterator = new TitleIterator();
    return titleIterator;
  }
}

上面的程式碼生成以下結果。

A
B

範例

下面的程式碼有一個區域性內部類繼承自另一個公共類。

import java.util.Random;

abstract class IntGenerator {
  public abstract int getValue() ;
}
class LocalGen {
  public IntGenerator getRandomInteger() {
    class RandomIntegerLocal extends IntGenerator {
      @Override
      public int getValue() {
        Random rand = new Random();
        long n1 = rand.nextInt();
        long n2 = rand.nextInt();
        int value = (int) ((n1 + n2) / 2);
        return value;
      }
    }

    return new RandomIntegerLocal();
  } // End of getRandomInteger() method
}

public class Main {
  public static void main(String[] args) {
    LocalGen local = new LocalGen();
    IntGenerator rLocal = local.getRandomInteger();
    System.out.println(rLocal.getValue());
    System.out.println(rLocal.getValue());
  }
}

上面的程式碼生成以下結果(每次的結果可能不太一樣)。

453673065
1036946998

匿名內部類

匿名內部類沒有名稱。 因為它沒有名稱,所以它不能有建構函式。匿名類是一次性類。定義一個匿名類並同時建立它的物件。
建立匿名類及其物件的一般語法如下:

new Interface()  {
// Anonymous  class body  goes  here
}

或者 -

new Superclass(<argument-list-for-a-superclass-constructor>)  {
// Anonymous  class body  goes  here
}

new運算子用於建立匿名類的範例。它後面是現有的介面名稱或現有的類名稱。介面名稱或類名稱不是新建立的匿名類的名稱。如果使用介面名稱,則匿名類實現介面。如果使用類名,則匿名類繼承自其它類。
僅當新運算子後面跟有類名時,才使用<argument-list>。 如果新運算子後跟介面名稱,則它為空。
如果<argument-list>存在,它包含要呼叫的現有類別建構函式的實際引數列表。

匿名類主體像往常一樣在大括號中。匿名類主體應該簡短,以便更好的可讀性。下面的程式碼包含一個簡單的匿名類,它在標準輸出上列印一條訊息。

public class Main {
  public static void main(String[] args) {
    new Object() {
      // An instance initializer

        System.out.println("Hello from  an  anonymous class.");
      }
    }; // A semi-colon is necessary to end the statement
  }
}

上面的程式碼生成以下結果。

Hello from  an  anonymous class.

範例-2

以下程式碼使用匿名類來建立疊代器(Iterator)。

import java.util.ArrayList;
import java.util.Iterator;

public class Main {
  private ArrayList<String> titleList = new ArrayList<>();

  public void addTitle(String title) {
    titleList.add(title);
  }

  public void removeTitle(String title) {
    titleList.remove(title);
  }

  public Iterator<String> titleIterator() {
    // An anonymous class
    Iterator<String> iterator = new Iterator<String>() {
      int count = 0;

      @Override
      public boolean hasNext() {
        return (count < titleList.size());
      }

      @Override
      public String next() {
        return titleList.get(count++);
      }
    }; // Anonymous inner class ends here

    return iterator;
  }
}