内部类的使用
类的内部成员之五:内部类
1、java中允许将一个类A声明在另一个类B中,则类A就是内部类,类B称为外部类
2、内部类的分类:成员内部类(静态、非静态) vs 局部内部类(方法内、代码块内、构造器内)
3、成员内部类:
一方面,作为外部类的成员:
-调用外部类的结构
-可以被static修饰
-可以被4种不同的权限修饰
另一方面,作为一个类:
-类内可以定义属性、方法、构造器等
-类可以用final修饰,表示此类不能被继承。
-可以被abstract修饰,表示此类不能被实例化
4、重点关注如下三个问题:
-如何实例化成员内部类的对象
-如何在成员内部类中,区分调用外部类的结构
-局部内部类的使用
5、在局部内部类的方法中,如果调用局部内部类所声明的方法中的局部变量的话,要求此局部变量声明为final。
jdk 7 及之前版本,要求此局部变量显式的声明为final。
jdk 8 及之后的版本,可以省略final 的声明。
总结:成员内部类和局部内部类,在编译以后,都会生成字节码文件。
格式:成员内部类:外部类$内部类名.class
局部内部类:外部类$数字 内部类名.class
public class InnerClassTest { public static void main(String[] args) { //创建Brain实例(静态的成员内部类) Person.Brain brain = new Person.Brain(); brain.think(); //创建bond实例(非静态的成员内部类) Person p1 = new Person(); Person.Bond bond = p1.new Bond(); bond.breakbond(); } } class Person{ int age; String name; public void eat() { System.out.println("eat health!"); } //静态成员内部类 static class Brain{ public void think() { System.out.println("人需要不断思考!");
System.out.println(age);//此变量会自动默认为final修饰
} } //非静态成员内部类 class Bond{ String name; public Bond() { } public void breakbond() { System.out.println("be careful!"); eat(); Person.this.eat();//调用外部类的结构 } public void method1(String name) { System.out.println(name);//方法的形参 System.out.println(this.name);//内部类的属性 System.out.println(Person.this.name);//外部类的属性 System.out.println(age); } } public void method1() { //方法内的局部内部类 class A{ } } {//代码块内的局部内部类 class B{ } } public Person(){ //构造器内的局部内部类 class C{ } } }
//局部内部类的使用场景,实际开发过程中用的很少,看源码时会遇到。 public class InnerClassTest1 { public void method() { //局部内部类使用1:实际开发中不会用到这种返回void的内部类使用方法
class AA{ } } //使用2:返回一个实现了Comparable接口的类的对象 public Comparable getComparable() { //方式1:创建一个实现了Comparable接口的类:局部内部类 // class MyComparable implements Comparable{ // @Override // public int compareTo(Object o) { // return 0; // } // } // // return new MyComparable(); //方式2:创建一个实现了Comparable接口的匿名实现类的匿名对象 return new Comparable() { public int compareTo(Object o) { return 0; } }; } }