1、什么是内部类
可以将一个类的定义放在另一个类的内部,这就是内部类。广义上我们将内部类分为四种:成员内部类,静态内部类、局部(方法)内部类、匿名内部类。
/*** 我是一个外部类(外部是相对内部而言)*/public class Outer{/*** 我是一个内部类*/class Inner{//...}}
2、为什么使用内部类
使用内部类最吸引人的原因是:每个内部类都唔那个独立的继承一个(接口的)实现,所以无论外围类是否已经继承了某个(接口的)实现,对于内部类都没有影响。——《Think in java》
也就是说内部类拥有类的基本特征。(eg:可以继承父类,实现接口。)在实际问题中我们会遇到一些接口无法解决或难以解决的问题,此时我们可以使用内部类继承某个具体的或抽象的类,间接解决类无法多继承引起的一系列问题。(注:内部类可以嵌套内部类,但是这极大的破坏了代码的结构,这里不推荐使用。)
/**1. Outer类继承了ClassA,实现了IFunctionA*/public class Outer extends ClassA implements IFunctionA{/*** Inner类继承了ClassB,实现了IFunctionB*/public class Inner extends ClassB implements IfunctionB{//}}
除了上面的优点之外还有如下四点:
- 内部类可以用多个实例,每个实例都有自己的状态信息,并且与其他外围对象的信息相互独立。
 - 内部类并没有令人迷惑的“is-a”关系,他就是一个独立的实体。
 - 内部类提供了更好的封装,除了该外围类,其他类都不能访问。
 - 创建内部类对象的时刻并不依赖于外围类对象的创建。
 
具体来说,内部类信息(属性、方法)可以和外部类重名;内部类是具有类的基本特征的独立实体;可以利用访问修饰符隐藏内部类的实施细节,提供了更好的封装;静态内部类使用时可直接使用,不需先创造外部类。
简单总结:
一、成员内部类
1,外部类,内部类
/*** 外部类、成员内部类的定义*/public class Outer {private int outerVariable = 1;private int commonVariable = 2;private static int outerStaticVariable = 3;//省略getter/setter/*** 成员方法*/public void outerMethod() {System.out.println("我是外部类的outerMethod方法");}/*** 静态方法*/public static void outerStaticMethod() {System.out.println("我是外部类的outerStaticMethod静态方法");}/*** 内部类*/public class Inner {private int commonVariable = 20;/*** 构造方法*/public Inner() {}/*** 成员方法,访问外部类信息(属性、方法)*/public void innerShow() {//当和外部类冲突时,直接引用属性名,是内部类的成员属性System.out.println("内部的commonVariable:" + commonVariable);//内部类访问外部属性System.out.println("outerVariable:" + outerVariable);//当和外部类属性名重叠时,可通过外部类名.this.属性名System.out.println("外部的commonVariable:" + Outer.this.commonVariable);System.out.println("outerStaticVariable:" + outerStaticVariable);//访问外部类的方法outerMethod();outerStaticMethod();}}/*** 外部类访问内部类信息*/public void outerShow() {Inner inner = new Inner();inner.innerShow();}}
2.其他类使用成员内部类
/** 其他类使用成员内部类*/public class Other {public static void main(String[] args) {//外部类对象Outer outer = new Outer();//创造内部类对象Outer.Inner inner = outer.new Inner();inner.innerShow();/** 可在Outer中定义get方法,获得Inner对象,那么使用时,只需outer.getInnerInstance()即可。* public Inner getInnerInstance(Inner类的构造方法参数){* return new Inner(参数);* }*/}}
3.小结
- 可以是任何的访问修饰符。
 - 内部类的内部不能有静态信息。
 - 内部类也是类,该继承继承,该重写重写,该重载重载,this和super随便用。
 - 外部类如何访问内部类信息,必须new之后打点访问。
 - 内部类可以直接使用外部类的任何信息,如果属性或者方法发生冲突,调用外部类.this.属性或者方法。
 
二、静态内部类
/*** 外部类、内部类定义*/public class Outer {private int outerVariable = 1;/*** 外部类定义的属性(重名)*/private int commonVariable = 2;private static int outerStaticVariable = 3;static {System.out.println("Outer的静态块被执行了……");}/*** 成员方法*/public void outerMothod() {System.out.println("我是外部类的outerMethod方法");}/** 静态方法*/public static void outerStaticMethod() {System.out.println("我是外部类的outerStaticMethod静态方法");}/*** 静态内部类*/public static class Inner {/*** 成员信息*/private int innerVariable = 10;private int commonVariable = 20;static {System.out.println("Outer.Inner的静态块执行了……");}private static int innerStaticVariable = 30;/*** 成员方法*/public void innerShow() {System.out.println("innerVariable:" + innerVariable);System.out.println("内部的commonVariable:" + commonVariable);System.out.println("outerStaticVariable:"+outerStaticVariable);outerStaticMethod();}/*** 静态方法*/public static void innerStaticShow() {//被调用时会先加载Outer类outerStaticMethod();System.out.println("outerStaticVariable"+outerStaticVariable);}}/*** 外部类的内部如何和内部类打交道*/public static void callInner() {System.out.println(Inner.innerStaticVariable);Inner.innerStaticShow();}}
2、其他类使用成员内部类
public class Other {public static void main(String[] args) {//访问静态内部类的静态方法,Inner类被加载,此时外部类未被加载,独立存在,不依赖于外围类。Outer.Inner.innerStaticShow();//访问静态内部类的成员方法Outer.Inner oi = new Outer.Inner();oi.innerShow();}}
3、小结
- 内部可以包含任意的信息。
 - 静态内部类的方法只能访问外部类的static关联的信息
 - 利用 外部类.内部类 引用=new 外部类.内部类(); 然后利用引用.成员信息(属性、方法)调用。
 - 访问内部类的静态信息,直接外部类.内部类.静态信息就可以了。
 - 静态内部类可以独立存在,不依赖于其他外围类。
 
局部内部类
1、内部类,外部类
/*** 外部类、内部类*/public class Outer {/*** 属性和方法*/private int outerVariable = 1;/*** 外部类定义的属性*/private int commonVariable = 2;/*** 静态的信息*/private static int outerStaticVariable = 3;/*** 成员外部方法*/public void outerMethod() {System.out.println("我是外部类的outerMethod方法");}/*** 静态外部方法*/public static void outerStaticMethod() {System.out.println("我是外部类的outerStaticMethod静态方法");}/*** 程序的入口*/public static void main(String[] args) {Outer outer = new Outer();outer.outerCreatMethod(100);}/*** 成员方法,内部定义局部内部类*/public void outerCreatMethod(int value) {/*** 女性*/boolean sex = false;/*** 局部内部类,类前不能有访问修饰符*/class Inner {private int innerVariable = 10;private int commonVariable = 20;/*** 局部内部类方法*/public void innerShow() {System.out.println("innerVariable:" + innerVariable);//局部变量System.out.println("是否男性:" + sex);System.out.println("参数value:" + value);//调用外部类的信息System.out.println("outerVariable:" + outerVariable);System.out.println("内部的commonVariable:" + commonVariable);System.out.println("外部的commonVariable:" + Outer.this.commonVariable);System.out.println("outerStaticVariable:" + outerStaticVariable);outerMethod();outerStaticMethod();}}//局部内部类只能在方法内使用Inner inner = new Inner();inner.innerShow();}}
2、小结
- 类前不能有访问修饰符。
 - 仅在此方法内使用。
 - 无法创造静态信息。
 - 可以直接访问方法内的局部变量和参数(有限制),但是不能更改。
 - 可以随意的访问外部类的任何信息。
 
四、匿名内部类
1、定义接口
/*** 接口中方法默认为public*/public interface IAnimal{void speak();}
2、匿名内部类的使用
/*** 外部内、内部类*/public class Outer {public static IAnimal getInnerInstance(String speak){return new IAnimal(){@Overridepublic void speak(){System.out.println(speak);}};//注意上一行的分号必须有}public static void main(String[] args){//调用的speak()是重写后的speak方法。Outer.getInnerInstance("小狗汪汪汪!").speak();}}
- 匿名内部类是没有访问修饰符的。
 - 使用匿名内部类时,这个new之后的类首先是要存在的,其次我们要重写new后的类的某个或某些方法。
 - 匿名内部类访问方法参数时也有和局部内部类同样的限制。
 - 匿名内部类没有构造方法。
 
此文部分转载自:https://blog.csdn.net/weixin_42762133/article/details/82890555
更详细请移步。
