什么是内部类呢?简单来说内部类就是:一个类中,包含了另一个一个类。
java中内部类的出现主要是为了访问外部类数据的便捷性,一般用于类的设计。
内部类的特点:
内部类可以直接访问外部类的成员,外部类访问内部类,必须建立内部类的对象、
如下是内部类的简单例子:
class Outer { private int num = 3; public void method() {
new Inner().show(); } //将Inner放在Outer类中,Inner就是Outer的内部类 class Inner {
private int num=4; void show() {
int num=5; System.out.println(Outer.this.num); //输出外部类的num 3
System.out.println(Inner.this.num);//输出内部类num 4
}}System.out.println(num); //输出局部变量num 5
}
那么在这里对于内部类的访问有如下几种情况:
在第三个类中对内部类进行创建和访问:
当内部类是静态时:我们需要注意Outer.Inner in=new Outer().new Inner(); in.show();
Outer.Inner in=new Outer.Inner(); in.show();
当内部类中的方法是static修饰时,我们应该注意static对类加载的影响:
package com.whpudu.test; class Outer{ static int num=5; static class Inner{ static int num=4; static void show() { System.out.println(Outer.num);
}}}public class OuterInner { public static void main(String[] args) { Outer.Inner.show();}}System.out.println(Inner.num);
还有一个是局部内部类,局部内部类中,我们只需要注意一个地方即:局部内部类中访问局部变量必须加final修饰,java8中只要是局部内部类访问局部变量就默认有final修饰
package com.whpudu.test; class Outer{ void method() { final int num=3; //java8中默认加了final修饰符 class Inner{ void show() { System.out.println(num); } } new Inner().show(); } } public class OuterInner { public static void main(String[] args) { new Outer().method(); } }
在这里为什么要加final修饰符呢?主要是因为new Inner()以后需要对num进行调用,num是局部变量,如果不加final修饰符,可能在一次调用以后num可能就销毁了,然而对象还在,对象可以对num进行多次调用,这时再调用num,就会出错,因为num在内存中已经销毁不存在了,当然因为java8的特性,很多人会忽视这个问题。所以在这里写出来,让大家警醒。
匿名内部类的实质是:实现(覆写)父类方法的子类对象
只要我们抓住了这一点实质,对于匿名内部类我们就不会有太大的问题。下面是匿名内部类的代码示例:
class Fu{ void show() {} ; } class Outer{ void method() { new Fu(){ void show() { System.out.println("这是复写父类的的方法"); } }.show(); } } public class OuterInner { public static void main(String[] args) { } }
从代码中,我们能很清楚的看到匿名内部类就是一个覆写父类方法的子类对象,匿名内部类一般适用于传递形参,这类只使用一次,不需要专门为它创建一个类和对象。
在匿名内部类中我们需要注意的是:
匿名内部类方法的调用:
package com.whpudu.test; class Fu{ void show1() {} ; void show2() {} ; } class Outer{ void method() { Fu fu=new Fu(){ void show1() { System.out.println("这是复写父类的show1方法"); } void show2() { System.out.println("这是复写父类的show2方法"); } void show3() { System.out.println("这是子类特有的方法"); } }; fu.show1(); fu.show2(); //fu.show3(); 这里要理解多态,我们把子类对象向上转型为Fu类,所有无法再调用子类的特有方法了,这里会报编译错误 } } public class OuterInner { public static void main(String[] args) { new Outer().method(); } }
这一种方式运用多态:给子类对象取名,这种方法因为向上转型所以调用不了子类特有的方法
第二中方式:这一种方式我不知道原理,只是无意间看到这个方法可以运行,就写出来,供大家参考
package com.whpudu.test; class Fu{ void show1() {} ; void show2() {} ; } class Outer{ void method() { new Fu(){ void show1() { System.out.println("这是复写父类的show1方法"); } void show2() { System.out.println("这是复写父类的show2方法"); } void show3() { System.out.println("这是子类特有的方法"); } {show1();show2();show3();}}; } } public class OuterInner { public static void main(String[] args) { new Outer().method(); } }