1.内部类的初步介绍
1.1 内部类的定义
当我们将一个类A放置于另一个类B的内部定义时,那么我们称A为内部类(或嵌套类),称B为外部类(或宿主类)。
1.2 内部类的主要作用
① 内部类提供了更好的封装效果,可以将内部类隐藏在外部类之内,在内部类中完成封装效果;
② 内部类成员可以直接访问外部类的私有数据,可以作为外部类的成员,一个类中的成员可以相互访问;
③ 匿名内部类可以用于创建仅需要使用一次的类;
1.3 内部类与外部类的区别
① 内部类可以使用private、protected、static修饰符修饰,外部类不能;
② 非静态内部类不能有静态成员;
2.非静态内部类
2.1内部类划分及非静态内部类简介
在外部类的方法中定义的类为局部内部类;
定义在外部类中的类为成员内部类,成员内部类与类中的其他成员相似,可以相互访问,成员内部类分两种,使用static修饰的内部类为静态内部类,无static修饰的内部类为非静态内部类;
2.2非静态内部类示例
例如,我们在Cow类中定义一个ComLeg的非静态内部类,并在CowLeg类的实例方法中可以直接访问外部类Cow的private修饰的实例变量。代码如下:
public class Cow {
// 外部类的私有实例成员变量
private double weight;
// 外部类的构造器
public Cow() {}
public Cow(double weight) {
this.weight = weight;
}
// 定义非静态内部类
private class CowLeg{
// 非静态内部类的私有成员变量
private double length;
private String color;
// 非静态内部类的构造器
public CowLeg() {}
public CowLeg(double length, String color) {
this.length = length;
this.color = color;
}
// 在内部类中实现封装
public double getLength() {
return length;
}
public void setLength(double length) {
this.length = length;
}
public String getColor() {
return color;
}
public void setColor(String color) {
this.color = color;
}
// 在内部类中的info方法,输出信息
public void info() {
System.out.println("牛腿的颜色是:" + color + ",高为:" + length);
// 当外部类的私有成员初始化后,便可以访问外部类的私有成员
System.out.println("在内部类中查看奶牛的重量:" + weight);
}
}
// 在外部类中利用test方法,创建CowLeg对象,调用内部类的构造器
public void test() {
CowLeg l = new CowLeg(1.2 , "黑色");
l.info();
}
public static void main(String[] args) {
// 创建Cow对象,并初始化私有成员变量weight
Cow cow = new Cow(400);
// 使用test方法,输出内部类的运行结果
cow.test();
}
}
运行结果为:
牛腿的颜色是:黑色,高为:1.2
在内部类中查看奶牛的重量:400.0
在编译上述文件时,文件夹中会有两个class文件,一个为Cow.class,另一个为Cow$CowLeg.class,一个是外部类的文件,一个是内部类的存储文件。
2.3对代码的图解
对于2.2中的存储方式如图所示:
2.4对于非静态内部类的注意事项
- 外部类不能直接访问非静态内部类的实例变量,必须显示的创建内部类对象;
- 不允许在外部类的静态成员中直接使用非静态内部类;
- 不允许在非静态内部类中定义静态成员;
示例代码如下:
public class Demo {
class Inner{
// 内部类的成员变量
private int num = 2;
// 非静态内部类中不能有静态static声明
// private static int a = 1;
}
public void idea() {
// 显式创建内部类对象
System.out.println("内部类num变量的值为:" + new Inner().num);
}
public static void main(String[] args) {
// 创建了demo对象时,内部类对象还未创建
Demo demo = new Demo();
demo.idea();
// 下面代码异常,不能在外部类的静态内部类中直接使用非静态内部类
// new Inner();
}
}
3.静态内部类
3.1静态内部类的使用规则
- 使用static修饰的内部类为静态内部类,也叫类内部类,静态内部类与类相关,而不是与实例相关,属于整个类,而不是属于单个的对象;
- 静态内部类可以包含静态成员与非静态成员;
- 静态内部类不能访问外部类的实例成员,只能访问外部类的类成员;
- 外部类的所有方法、所有初始化块中都可以使用静态内部类;
- 外部类不能直接访问静态内部类的成员,但是可以使用静态内部类的类名调用其类成员,或者可以使用静态内部类为对象来访问其实例成员;
- 接口里也可是使用内部类,默认用public static修饰;
3.2静态内部类规则的示例
代码如下:
public class Demo {
private int num1 = 1;
private static int num2 = 2;
static class StaticInner {
// 静态内部类可以包含静态和非静态成员变量
private static int use = 1;
private int age = 2;
public void idea() {
// 静态内部类无法访问外部类的非静态成员变量
// System.out.println("静态内部类访问外部类的非静态成员变量:" + num1);
// 静态内部类可以访问外部类的静态成员变量
System.out.println("静态内部类访问外部类的静态成员变量:" + num2);
}
}
public void access() {
// 外部类通过类名访问静态内部类的类成员
System.out.println(StaticInner.use);
// 外部类通过实例访问静态内部类的实例成员
System.out.println(new StaticInner().age);
}
}
未完待续……