当一个事物的内部,还有一个部分需要一个完整的结构进行描述,而这个内部的完整的结构又只为外部事物提供服务,那么这个内部的完整结构最好使用内部类。在 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();

   }

}