可以將一個類的定義放在另一個類的定義內部,這就是內部類。
普通內部類:
public class InnerDemo {
private Object[] item = { 2, 12, 3 };
public void print() {
System.out.println("aaaa");
}
public static void main(String[] args) {
InnerDemo id = new InnerDemo();
//如果想從外部類的非靜態方法之外的任意位置指明內部類類型OuterClassName.InnerClassName
InnerDemo.SelectorImpl selectorImpl = id.selector();
System.out.println(selectorImpl.end());
selectorImpl.init();
}
class SelectorImpl implements Selector {
private int i = 0;
public void init() {
InnerDemo id2 = new InnerDemo();
id2.print();
}
public boolean end() {
// 可以訪問外部內中的所有成員
return i == item.length;
}
}
public SelectorImpl selector() {
return new SelectorImpl();
}
}
interface Selector {
boolean end();
}
結論如下:
1.如果想從外部類的非靜態方法之外的任意位置指明內部類類型OuterClassName.InnerClassName。2.當生成一個內部類的對象時,此對象與製造它的外圍對象之間就有了一種聯繫,所以它能訪問其外圍對象的所有成員,而不需要任何特殊條件。此外,內部類還擁有其外圍類的所有元素的訪問權。
局部內部類:
public class LocalInner {
public Destination destination(String s) {
class PDestination implements Destination {
private String label;
private PDestination(String whereTo) {
label = whereTo;
}
}
return new PDestination(s);
}
public static void main(String[] args) {
LocalInner li = new LocalInner();
li.destination("Tokyo");// 這裏向上轉型,返回的是Destination的引用
}
}
interface Destination {
}
匿名內部類:
public class Dog {
public interface Pet {
public void beFriendly();
public void play();
}
public static void main(String[] args) {
Pet dog = new Pet() {
public void beFriendly() {
System.out.println("hello");
}
public void play() {
System.out.println("play");
}
};
dog.beFriendly();
dog.play();
}
}
接口不能new,但是可以以匿名內部類的形式在{}中實現接口中的方法。
下面有兩種匿名內部類的寫法:
public class Test {
public static void main(String[] args) {
// 這裏new Thread() {}是一個繼承Thread類的匿名內部類
java.lang.Runtime.getRuntime().addShutdownHook(new Thread() {
@Override
public void run() {
System.out.println("ssss");
}
});
}
}
public class Test {
public static void main(String[] args) {
// 在虛擬機關閉的時候進行一些操作,會在addShutdownHook方法裏面調用start方法,
// new Runnable() {}是一個實現Runnable接口的匿名內部類,然後作爲Thread構造器的參數傳入
java.lang.Runtime.getRuntime().addShutdownHook(new Thread(new Runnable() {
@Override
public void run() {
System.out.println("ssss");
}
}));
}
}
靜態嵌套類:
public class Outer {
private int y = 2;
private static int x = 1;
static class Nest {
void print() {
System.out.println(y); // 編譯報錯,只能訪問靜態變量
System.out.println("Nest " + x);
}
}
public static void main(String[] args) {
Outer.Nest nest = new Outer.Nest();
nest.print();
}
}
爲何要用內部類?
1. 內部類一般只爲其外部類使用;
2. 內部類提供了某種進入外部類的窗戶;
3. 也是最吸引人的原因,每個內部類都能獨立地繼承一個接口,而無論外部類是否已經繼承了某個接口。因此,內部類使多重繼承的解決方案變得更加完整。