引言:在Java中内部类是我们经常见到却容易忽略的,如线程对象Thread通过内部类Runnable实现多线程。我们都知道,Java语言是不支持多继承的,引入内部类可以解决Java单继承的缺陷。
一,内部类存在的意义
文章引言部分有说到,内部类的引入解决了Java单继承的缺陷。而它随之带来的还有以下几个优点:1,内部类可以对同一包中的其他类隐藏起来;2,当我们想要定义一个回调函数却不想写大量代码的时候我们可以选择使用匿名内部类来实现。
new Thread(new Runnable() {
public void run() {
for(int i=0;i<1000;i++) {
System.out.println(i);
}
}
}).start();
二,内部类与外部类的关系
- 对于非静态内部类,内部类的创建依赖外部类的实例对象,在没有外部类实例之前是无法创建的;
- 静态内部类是不依赖与外部类的创建,原因是 static并不依赖于实例,而依赖于类 Class 本身;
- 内部类是一个相对独立的实体,与外部类不是is-a (继承)关系。可以从以下2点说明:
- 一个外部类可以拥有多个内部类对象,而他们之间没有任何关系,是独立的个体;
- 从编译结果来看,内部类被表现为 「外部类$内部类.class 」,所以对于虚拟机来说他个一个单独的类来说没什么区别。但是我们知道他们是有关系的,因为内部类默认持有一个外部类的引用。
1,非静态内部类:
public class Outter {
private String name;
public class Inner {
public Inner () {
System.out.println("内部类创建");
}
}
}
public class InnerTest {
public static void main(String[] args) {
// 方式一
Outter.Inner inner1 = new Outter().new Inner();
// 方式二
Outter outter = new Outter();
Outter.Inner inner2 = outter.new Inner();
}
}
要点:正式由于这种依赖关系,所以普通内部类中不允许有 static 成员。我们知道 static本身是针对类本身而言的。我们的非 static内部类总是由一个外部的对象生成,既然与对象相关自然也就没有静态字段与方法;而静态内部类是不依赖于外部对象的所以其内允许有 static成员。
2,静态内部类:
public class Outter {
private String name;
public static class Inner {
// private static String times;
public Inner () {
System.out.println("静态内部类创建");
}
}
}
public class InnerTest {
public static void main(String[] args) {
Outter.Inner inner = new Outter.Inner();
}
}
3,静态内部类与非静态内部类的区别:
- 静态内部类可以有静态成员,而非静态内部类则不能有静态成员;
- 静态内部类可以访问外部类的静态变量,而不可访问外部类的非静态变量;
- 非静态内部类的非静态成员可以访问外部类的非静态变量。
- 静态内部类的创建不依赖于外部类,而非静态内部类必须依赖于外部类的创建而创建。
public class Outter {
private String name;
private static String static_name;
public class Inner {
public Inner () {
System.out.println("非静态内部类访问外部类非静态成员: " + name);
System.out.println("非静态内部类访问外部类静态成员: " + static_name);
}
}
public static class StaticInner {
public StaticInner () {
// System.out.println("静态内部类访问外部类非静态成员: " + name);
System.out.println("静态内部类访问外部类静态成员: " + static_name);
}
}
}
public class InnerTest {
public static void main(String[] args) {
// 实例化非静态内部类
Outter.Inner inner = new Outter().new Inner();
// 实例化静态内部类
Outter.StaticInner staticInner = new Outter.StaticInner();
}
}
完