一、内部类概述
1. 定义在其他类内部的类就被称为内部类,包含内部类的类也被称为外部类
2. 内部类提供了更好的封装,它隐藏在外部类之内,不允许同一个包中的其他类访问该类
3. 内部类作为外部类的成员,可以直接访问外部类的私有数据,但外部类不能访问内部类的实现细节
4. 内部类比外部类可以多使用三个修饰符:private、protected、static
5. 定义在方法中的内部类被称为局部内部类,定义在外部类中其他位置的内部类被称为成员内部类
- 成员内部类是一种与成员变量、方法、构造器和初始化块相似的类成员,而局部内部类和匿名内部类则不是类成员
6. 大部分时候,内部类都被作为成员内部类定义,成员内部类分为两种:非静态内部类、静态内部类,后者需使用static修饰
二、非静态内部类
// 外部类Cow:奶牛
public class Cow
{
private double weight;
public Cow() {}
public Cow(double weight)
{
this.weight = weight;
}
// 定义一个非静态内部类CowLeg:牛腿
private class CowLeg
{
private double length;
private String color;
public CowLeg() {}
public CowLeg(double length, String color)
{
this.length = length;
this.color = color;
}
// 非静态内部类的实例方法
public void info()
{
System.out.println("当前牛腿颜色是:" + color + ", 高:" + length);
// 直接访问外部类的私有成员变量weight
System.out.println("本牛腿所属的奶牛重:" + weight);
}
}
public void test()
{
// 在外部类里使用非静态内部类,与使用普通类没有太大区别
CowLeg cl = new CowLeg(1.12, "黑白相间");
cl.info();
}
public static void main(String[] args)
{
Cow cow = new Cow(378.5);
cow.test();
}
}
1. 非静态内部类不能拥有静态成员,即非静态内部类里不能有静态成员变量、静态方法、静态初始化块
2. 由于静态成员不能访问非静态成员,故不允许在外部类的静态成员中直接使用非静态内部类
3. 非静态内部类的成员可以直接访问外部类的private成员,因为内部类被当成其外部类的成员
4. 如果外部类需要访问非静态内部类的实例成员,则必须显式创建非静态内部类对象来调用访问其实例成员
public class Outer
{
class Inner
{
private int inProp = 5;
}
// 错误示范:外部类不能直接访问非静态内部类的实例成员
System.out.println("内部类的inProp值:" + inProp);
// 正确示范:显式创建内部类对象,由其调用内部类实例成员
System.out.println("内部类的inProp值:" + new Inner().inProp);
}
4. 如果外部类成员变量、内部类成员变量以及内部类里方法的局部变量同名,则可通过使用外部类类名.this、this作为限定来区分
- 通过外部类类名.this.varName访问外部类实例变量,通过this.varName访问内部类实例变量
三、静态内部类
1. 静态内部类属于外部类本身,而不属于外部类的某个对象
2. 静态内部类既可以包含静态成员,也可以包含非静态成员
3. 由于静态内部类是外部类的一个静态成员,故允许在外部类的所有成员中直接使用静态内部类
4. 由于静态成员不能访问非静态成员,故静态内部类不能访问外部类的实例成员,只能访问外部类的类成员
5. 如果外部类需要访问静态内部类的成员,则必须使用静态内部类类名/对象作为调用者来访问静态内部类的类成员/实例成员
四、使用内部类