概述
即在类中定义另一个类,是一个相对的概念。
分为成员内部类和局部内部类
定义时是一个正常定义的过程,同样包含修饰符 继承 实现关系等
内部类可以直接访问外部类的所有成员
外部类编译后会出现两个class文件
demo1:非静态成员内部类
public class OutClass {
private String addr="上海";
private void outshow() {
System.out.println("OutClass_outshow");
}
public class InClass {
public void inShow() {
System.out.println("InClass_inshow");
System.out.println(addr);
Outshow();
}
}
}
public class TestInclass {
public static void main(String[] args) {
OutClass oc= new OutClass();
InClass ic=oc.new InClass();//实例方式
ic.inShow();
}
}
InClass_inshow
上海
OutClass_outshow
非静态成员内部类实例化需要先创建内部类,再通过外部类.new 内部类():InClass ic=new OutClass().new InClass(); |
demo2:静态成员内部类
public class OutClass {
private static String addr="上海";
private static void outshow() {
System.out.println("OutClass_outshow");
}
public static class InClass {
public void inShow() {
System.out.println("InClass_inshow");
System.out.println(addr);
Outshow();
}
}
}
InClass改为static后,addr和outshow()也需要改为static,不然静态块调用非静态块,编译不通过。
public class TestInclass {
public static void main(String[] args) {
OutClass.InClass in=new OutClass.InClass();
in.inShow();
}
}
InClass_inshow
上海
OutClass_outshow
编译后的class:
静态成员内部类:OutClass.InClass in=new OutClass.InClass(); |
demo3:局部内部类
public class OutClass {
private static String addr="上海";
public void outShow() {
int x=100;
System.out.println("OutClass_outShow");
class InClass{
private String name="wyq";
public void innerMethod() {
System.out.println("InClass_innerMethod");
System.out.println("外部类的成员变量_"+addr);
System.out.println("外部类的局部变量_"+x);
}
}
//创建
InClass in=new InClass();
in.innerMethod();
}
}
public class TestInclass {
public static void main(String[] args) {
OutClass oc=new OutClass();
oc.outShow();//只有执行外部类outShow()时 才会创建内部类 并执行方法
}
}
OutClass_outShow
InClass_innerMethod
外部类的成员变量_上海
外部类的局部变量_100
局部内部类只有在执行外部类对应的方法时才能创建该对象,并且执行。 | |
jdk1.8之前局部内部类如果要使用外部类的局部变量(x),必须用final修饰它 |
demo4:匿名内部类
创建一个交通工具接口:
public interface Vehicle {
void run();
}
创建一个驾驶类
public class Driver {
public void driver(Vehicle v) {
System.out.println("开始驾驶"+v);
}
}
TestDriver:
这时候我们发现需要传入一个交通工具的实现类,但我们只写了接口,因此使用匿名内部类:
public class TestDriver {
public static void main(String[] args) {
Driver d=new Driver();
d.driver(new Vehicle() {
@Override
public void run() {
System.out.println("交通工具启动。。。");
}
});
}
}
匿名类只能使用一次,没有名字(没有用引用接收它) |
总结:
Inner Class |
---|
非静态成员内部类实例化需要先创建内部类,再通过外部类.new 内部类():InClass ic=new OutClass().new InClass(); |
静态成员内部类:OutClass.InClass in=new OutClass.InClass(); |
局部内部类只有在执行外部类对应的方法时才能创建该对象,并且执行。 |
jdk1.8之前局部内部类如果要使用外部类的局部变量,必须用final修饰它 |
匿名类只能使用一次,没有名字 |
匿名内部类使用场景:
需要一个接口/抽象类的对象,或者一个具体的类的子类对象 | |
已有的子类/实现类不能满足需求 | |
这个类只使用一次 |