可以将一个类的定义放在另一个类的定义内部,这就是内部类。
普通内部类:
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();
}
}
与一般内部类不同,在静态代码中不能够使用this操作,所以在静态内部类中只可以访问外部类的静态变量和静态方法,而不能访问实例成员。使用静态内部类的目的和使用内部类相同。如果一个内部类不依赖于其外部类的实例变量,或与实例变量无关,则选择应用静态内部类。
为何要用内部类?
1. 内部类一般只为其外部类使用;
2. 内部类提供了某种进入外部类的窗户;
3. 也是最吸引人的原因,每个内部类都能独立地继承一个接口,而无论外部类是否已经继承了某个接口。因此,内部类使多重继承的解决方案变得更加完整。