Java內部類類型
可以在類中的任何位置定義內部類,並在其中編寫Java語句。有三種類型的內部類。 內部類的類型取決於位置和聲明的方式。
- 成員內部類
- 局部內部類
- 匿名內部類
成員內部類
成員內部類在類中聲明的方式與聲明成員字段或成員方法相同。它可以聲明爲public
,private
,protected
或package-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;
}
}
局部內在類
一個局部內部類在塊中聲明。 其範圍僅限於聲明它的塊。由於其範圍限於其封閉塊,因此其聲明不能使用任何訪問修飾符,例如public
,private
或protected
。
通常,在方法內定義局部內部類。 但是,它也可以在靜態初始化器,非靜態初始化器和構造器中定義。下面的代碼顯示了一個局部內部類的例子。
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;
}
}