平常我们定义一个类的时候,类名需和类文件名相同,并且访问权限只能使用public和default。而内部类是指在外部类的内部再定义一个类,类名不需要和文件名相同。内部类可以是静态static的,也可用public,default(包限定),protected和private修饰。
内部类:
在java中内部类分为,成员内部类(非静态内部类,和静态内部类),匿名内部类,局部类内部类。
内部类是一个编译是的概念,一旦编译成功,就会成为完全不同的两个类,分别为outer.class
和outer$inner.class
类。所以内部类的成员变量/方法名可以和外部类的相同
1)、非静态内部类
1、非静态内部类必须寄存在外部类当中
2、非静态内部类可以访问外部成员变量,甚至是外部的私有成员变量,但是外部类不能直接访问非静态内部类成员。
3、非静态内部类不能有,静态变量,静态代码块,但是可以含有静态常量
4、外部类的静态代码块,静态方法,不能访问非静态内部类的,也不能使用非静态内部类定义变量,创建实例
package innerCalss;
/**
* @author hao
* @create 2019-07-10 ${TIM}
*/
public class InnerClassTest1 {
public static void main(String[] args) {
// 创建内部类
OuterClass.Inner inner = new OuterClass().new Inner();
inner.show(); // 输出结果:10
}
}
//外部类
class OuterClass{
private int age = 10;
//非静态成员内部类、
class Inner{
//static int age; 不能使用静态变量 编译会报错
public void show(){
System.out.println(OuterClass.this.age); //访问外部类的成员变量
}
}
}
打开编译之后的文件,会发现其实外部类和内部类 分别都编译成了一个class文件
因为成员内部类需要先创建了外部类,才能创建它自己的。
// 创建内部类
OuterClass.Inner inner = new OuterClass().new Inner();
通过外部类.this.属性名
来访问外部类的属性
OuterClass.this.age
2)、静态内部类
静态内部类,在定义内部类的时候 使用static
修饰。
1、当一个静态内部类存在的时候,并不一定存在对应外部类的对象。因此静态内部类不访问外部类的,非静态变量,不能非静态方法(也就是说静态要对应静态)
2、通过new 外部类.内部类
创建内部类
package innerCalss;
/**
* @author hao
* @create 2019-07-10 ${TIM}
* 静态内部类
*/
public class InnserClassTest2 {
public static void main(String[] args) {
//创建 内部类
OuterClass2.Inner2 inner2 = new OuterClass2.Inner2();
inner2.show(); //输出结果 jack
}
}
class OuterClass2{
private int age = 10;
private static String name = "jack";
//创建静态内部类
static class Inner2{
public void show(){
// System.out.println(OuterClass2.this.age); 编译无法通过 不能访问外部类 非静态成员
System.out.println(name);
}
}
}
创建静态内部类:
OuterClass2.Inner2 inner2 = new OuterClass2.Inner2();
3)、匿名内部类
用来创建我们只需要用一次的类。
1、匿名内部类没有访问修饰符号
2、匿名内部类没有构造方法
public class InnserClassTest3 {
public static void main(String[] args) {
//匿名内部类
new Thread(){
@Override
public void run() {
}
}.start();
}
}
匿名内部类也是会编译成两个文件,因为匿名内部类没有类名,所以用1代替
局部内部类
指内部类定义在方法体内,只能在该方法或条件的作用域内才能使用,退出这写作用域就无法引用。
1、非静态内部类的所有限制对局部类同样成立。局部类不仅可以访问外部类的所有成员,还可以访问方法体的局部变量。(java7只能访问final修饰的变量,java8则不用)
class Outer{
private int age = 10;
public void show(){
//作用范围只有该方法内
class Inner4{
public void showAge(){
System.out.println(age);
}
}
//只能在方法内部定义
Inner4 inner = new Inner4();
inner.showAge();
}
}
内部类有什么优点:
1.内部类可以很好的实现隐藏细节,一般的非内部类,只能是public 或者default 但是内部类可以有private 和protect
2.内部类拥有外围类的所有元素的访问权限 (private修饰也能访问)
3.可是实现多重继承 (让多个内部类分别继承多个其他类,使外部类可以同时获取多个其他类的属性)
4.可以避免修改接口而实现同一个类中两种同名方法的调用。(外部类继承,让内部类实现接口)