1、什么是Java内部类?ide
能够将一个类的定义放在另外一个类的内部,这就是内部类。广义上咱们将内部类分为四种:成员内部类、静态内部类、局部(方法)内部类、匿名内部类。this
2、为何用内部类?.net
使用内部类最新引人的缘由是:每一个内部类都能独立地继承一个接口的实现,因此不管外部类是否已经继承了某个接口,对于内部类都没有影响。code
在实际问题中咱们遇到一些接口没法解决的问题,此时咱们能够使用内部类继承某个具体的或抽象的类,简介解决类没法多继承引发的一系列问题。对象
除了上面的有点外还有以下四个优势:blog
一、内部类能够用多个实例,每一个实例都有本身的状态信息,而且与其它外部对象的信息相互独立。继承
二、内部类并无使人迷惑的“is-a”关系,他就是一个独立的实体。接口
注:is-a为父子继承关系生命周期
三、内部类提供了更好地封装,除了外部类,其余类不能访问。get
四、建立内部类对象的时刻并不依赖于外部类对象的建立。
3、如何使用内部类
(一)成员内部类
一、直接上代码
package innerClass; 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 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(); } public static void main(String[] args) { Outer outer = new Outer(); Outer.Inner inner = outer.new Inner(); outer.outerShow(); inner.innerShow(); } }
二、运行结果
三、小结:
① 能够是任何的访问修饰符
② 内部类的内部不能有静态信息
③ 内部类也是类,可继承,可重写,可重载,this和super随便用
④ 外部类必须经过new才能访问内部类
⑤ 内部类能够直接使用外部类的任何信息,若是属性或方法名一致,调用外部类.this.属性或方法。
(二)静态内部类
一、直接上代码
package innerClass; public class Outer1 { 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(); } public static void main(String[] args) { Outer1 outer1 = new Outer1(); Outer1.Inner inner = new Outer1.Inner(); outer1.callInner(); Inner.innerStaticShow(); inner.innerShow(); } }
二、运行结果
三、小结:
① 内部能够包含任何信息
② 静态内部类的方法只能访问外部类的static的信息
③ 调用内部非静态方法(成员方法)
Outer.Inner inner = new Outer.Inner();
inner.inerShow();
④ 调用内部静态方法
Inner.innerStaticShow();
(三)局部(方法)内部类
一、直接上代码
public class Outer { public class Inner { private int commonVariable = 20; //构造方法 public Inner() { } //成员方法,访问外部类信息(属性、方法) public void innerShow() { class Inner2 { public void inner2Show(){ System.out.println("方法内部类"); } } Inner2 inner2 = new Inner2(); inner2.inner2Show(); } } }
输出结果可想而知,不写了
局部内部类只能在方法内使用。
(四)匿名内部类
一、直接上代码
public interface IAnimal { void speak(); }
public class animalOuter { public static IAnimal getInnerInstance(final String msg){ return new IAnimal() { @Override public void speak(String str) { System.out.println(str+" is " + msg); } }; } public static void main(String[] args) { animalOuter.getInnerInstance("江疏影").speak("my name"); } }
二、运行结果
三、小结:
① 匿名内部类没有访问修饰符
② 使用匿名内部类时,要重写这个匿名的内部类
③ 匿名内部类访问方法参数时也有和局部内部类一样的限制。
④ 匿名内部类没有构造方法。
⑤ 方法的参数必须用final修饰,这是为何呢?
感谢@Ken大神的赐教,受益不浅啊
局部变量的生命周期与内部类对象的生命周期不同,颇有可能局部变量死了,内部类对象还活着,因此定义为final,至关于拷贝一份局部变量供内部类对象调用