当一个事物的内部,还有一个部分需要一个完整的结构进行描述,而这个内部的完整的结构又只为外部事物提供服务,那么这个内部的完整结构最好使用内部类。在 Java 中,可以将一个类定义在另一个类或者一个方法的内部,前者称为内部类,后者称为外部类。内部类也是封装的一种体现。
/**
* 外部类
*/
public class Outer {
//...
/**
* 内部类
*/
class Inner {
//...
}
}
注:
我们一般将内部类分为四种:成员内部类、静态内部类、局部(方法内部类)、匿名内部类。
外部类的定义是相对于内部类而言的
2. 为什么要使用内部类
🍈使用内部类最吸引人的原因是:每个内部类都能独立地继承一个(接口的)实现,所以无论外围类是否已经继承了某个(接口的)实现,对于内部类都没有影响。——《Think in java》
🍈也就是说内部类拥有类的基本特征。(eg:可以继承父类,实现接口)在实际问题中我们会遇到一些接口无法解决或难以解决的问题,此时我们可以使用内部类继承某个具体的或抽象的类,间接解决类无法多继承引起的一系列问题。
注:内部类可以嵌套内部类,但是这极大的破坏了代码的结构,但是这里不推荐使用。
举个例子🌰
/**
1. OuterClass类继承了 A,实现了IFunctionA
*/
public class OuterClass extends A implements IFunctionA{
/**
* Inner类继承了 B,实现了IFunctionB
*/
public class InnerClass extends B implements IfunctionB{
//
}
}
除此之外,内部类还可以:
内部类可以用多个实例,每个实例都有自己的状态信息,并且与其他外围对象的信息相互独立。
内部类并没有令人迷惑的“is-a”关系,他就是一个独立的实体。
内部类提供了更好的封装,除了该外围类,其他类都不能访问。
创建内部类对象的时刻并不依赖于外围类对象的创建。
成员内部类
💢💢也叫作实例内部类,是最普通的内部类,它的定义为位于另一个类的内部,形如下面的形式:
// 实例内部类
class OuterClass {
public int data1 = 1;
public static int data2 = 2;
private int data3 = 3;
/*成员方法*/
public void OuterMethod() {
System.out.println("外部类的outerMethod方法");
}
/*静态方法*/
public static void OuterStaticMethod() {
System.out.println("外部类的outerStaticMethod静态方法");
}
/*同名方法*/
public void test() {
System.out.println("OutClass:: test()");
InnerClass innerClass = new InnerClass();
}
class InnerClass{
public int data1 = 10;
public int data4 = 4;
//public static int data5 = 5; // jdk8 不支持这样用,jdk17 支持
public static final int data5 = 5;
private int data6 = 6;
public void InnerShow() {
//访问内部类属性
System.out.println("data4:" + data4);
//内部类访问外部属性
System.out.println("data3:" + data3); //私有权限的外部类也可以访问
//当和外部类冲突时,直接引用属性名,是内部类的成员属性
System.out.println("data1:" + this.data1); // 默认为this
//当和外部类属性名重叠时,可通过外部类名.this.属性名
System.out.println("data1:" + OuterClass.this.data1); //访问外部类成员
// 访问外部类方法
OuterMethod();
OuterStaticMethod();
}
public void test(){
System.out.println("InnerClass:: test()");
}
}
/* 外部类访问内部类信息 */
public void OuterShow() {
InnerClass inner = new InnerClass();
inner.InnerShow();
}
}
public class Test {
/*其他类使用成员内部类*/
public static void main(String[] args) {
//创造内部类对象,两种实例化方法
OuterClass outer = new OuterClass(); //外部类对象
OuterClass.InnerClass inner1 = outer.new InnerClass();
OuterClass.InnerClass inner2 = new OuterClass().new InnerClass();
inner1.test();
inner1.InnerShow();
}
}