什么是内部类?
类中定义类,在一个类的内部定义一个完整的类就叫做内部类
例如:
public class TestInner { public static void main(String[] args) { Outer o = new Outer(); Outer.Inner inner = o.new Inner(); inner.inner_method(); } } class Outer{ int a = 20; //Outer类的成员变量 //类中定义类 class Inner{ //成员内部类 int a = 10; // static int b; 成员内部类中不能定义静态成员(静态方法 和 静态变量) public void inner_method(){ int a = 30; System.out.println(a); //局部变量 30 System.out.println(this.a); //内部类的成员变量 10 System.out.println(Outer.this.a); //外部类的成员变量 20 } } }
从上面程序中可以看出:
Inner就叫做Outer 的 内部类,也是两个完全独立的类
编译后内部类会会生成对应的.class文件,文件名Outer$Inner.class
可以访问外部类的私有属性,从而不破坏外部类的封装性
成员内部类:
在类里面的类就叫成员内部类
可以类比于成员变量,定义在类以内,方法以外。
还借助于上面的程序,
创建成员内部类对象,必须先创建外部类对象,再通过外部类对象.new 构造内部类对象
Outer outer = new Outer(); Outer.Inner inner = outer.new Inner();
外部类类名.this指向外部类的当前对象: System.out.println(Outer.this.a); //外部类的成员变量 20
成员内部类中不能有静态成员
public class TestMemberClass { public static void main(String[] args) { Outer o1 = new Outer(120); Outer o2 = new Outer(200); Outer.Inner in = o1.new Inner(); in.print(); } } class Outer{ private int a ; //Inner就叫做Outer 的 内部类,也是两个完全独立的类 //在类里面的类就叫成员内部类 /* * 1,内部类可以 访问外部类的私有成员,而不破坏封装 */ public Outer() { } public Outer(int a) { this.a = a; } public class Inner{ //成员内部类中不能有静态成员 //private int s = 20; int a = 123; public void print(){ //外部类类名.this指向外部类的当前对象 System.out.println(a);//123 System.out.println("---"+Outer.this.a);//120 } } }
Outer.this 代表外部类对象
Outer.this.外部类属性名 访问外部类属性
Outer.this.外部类方法名(实参) 访问外部类方法
静态内部类:
可以类比于静态变量,成员内部类加上static就是静态内部类。也是定义在类以内,方法以外,被static修饰。
class Outer{ static class Inner{ } }
创建的时候需要依赖类来创建对象:
Outer.Inner inner = new Outer.Inner();
静态内部类中只能访问外部类的静态成员
局部内部类:
也是类比于局部变量,要定义在方法以内!
class Outer{ public void method(){ //类写在方法的内部,就叫做局部内部类 class inner{ } } }
局部内部类创建对象的时候只能在定义它的方法内部进行创建;
class Outer{ private int a = 10; public void m1(){ final int b = 20; class Inner{ public void inner_method(){ System.out.println(a); //10 System.out.println(b); System.out.println("局部内部类方法"); } } Inner inner = new Inner(); inner.inner_method(); } }
并且局部内部类可以去访问外部类的私有属性
局部内部类也可以去访问它所在方法的局部变量,但是要求局部变量必须被final修饰
jdk 8.0开始,默认为局部变量添加final
匿名内部类:
特殊的局部内部类。局部内部类有的特征它都有
匿名内部类
使用的三个条件
- 1)特殊的局部内部类
- 2)继承一个类或者实现一个接口
- 3)只会创建该类的一个对象
匿名内部类的写法
new 接口(){实现方法};
匿名内部类无法定义构造方法
定义匿名内部类的写法:定义类、实现接口、new对象 三步合一
IA ia = new IA(){ //IA 接口名 匿名内部类想要实现的接口 public void m1() { System.out.println("匿名内部类"); } }; //ia引用 可以直接操作内部类中方法 ia.m1();
下面展示一个匿名内部类的具体用法:
package test; public class TestNiMingClass { public static void main(String[] args) { // TODO Auto-generated method stub Teacher t = School.getTeacher(0); t.teach(); } } class School{ public static Teacher getTeacher(int i){ //两个局部内部类 class Teacher1 implements Teacher{ public void teach(){ System.out.println("胡老师讲课"); } } class Teacher2 implements Teacher{ public void teach(){ System.out.println("刘老师讲课"); } } if (i%2 == 0) { //return new Teacher1(); //定义匿名内部类的写法 //定义类、实现接口、new对象 三步合一 //局部内部类用法 //return new Teacher1(); //匿名内部类用法 return new Teacher(){ public void teach(){ System.out.println("胡老师讲课"); } }; }else{ return new Teacher2(); } } } interface Teacher{ void teach(); }
匿名内部类的好处:
接口公开,接口的实现类作为内部类隐藏起来,强制弱耦合
缺点是匿名内部类的写法真难受,可读性太差