Java内部类

最后更新于:2022-04-01 14:26:56

内部类:——成员内部类——局部内部类——匿名内部类 按照内部类在类中定义的位置不同,可以分为如下两种格式: 成员位置(成员内部类) 局部位置(局部内部类) 成员内部类 外界如何创建对象 外部类名.内部类名 对象名 = 外部类对象.内部类对象; ### 成员内部类 内部类可以直接访问外部类的成员,包括私有; 外部类要想访问内部类的成员,必须创建对象;并且,(1)在B类访问A类的内部类C,格式:A.C  ac = new A().new C();——外部类.内部类 对象名 = 外部类对象.内部类对象(对象!前后都有括号)。(2)如果内部类C被static修饰以后,格式是:外部类名.内部类名 对象名 = new 外部类名.内部类名()(注意前面没括号,后面有括号)。 ~~~ /* 成员内部类的修饰符: private 为了保证数据的安全性 static 为了方便访问数据 注意:静态内部类访问的外部类数据必须用静态修饰。 案例:我有一个人(人有身体,身体内有心脏。) class Body { private class Heart { public void operator() { System.out.println("心脏搭桥"); } } public void method() { if(如果你是外科医生) { Heart h = new Heart(); h.operator(); } } } 按照我们刚才的讲解,来使用一下 Body.Heart bh = new Body().new Heart(); bh.operator(); //加了private后,就不能被访问了,那么,怎么玩呢? Body b = new Body(); b.method(); */ class Outer { private int num = 10; private static int num2 = 100; //内部类用静态修饰是因为内部类可以看出是外部类的成员 public static class Inner { public void show() { //System.out.println(num); System.out.println(num2); } public static void show2() { //System.out.println(num); System.out.println(num2); } } } class InnerClassDemo { public static void main(String[] args) { //使用内部类 // 限定的新静态类 //Outer.Inner oi = new Outer().new Inner(); //oi.show(); //oi.show2(); //成员内部类被静态修饰后的访问方式是: //格式:外部类名.内部类名 对象名 = new 外部类名.内部类名(); Outer.Inner oi = new Outer.Inner(); oi.show(); oi.show2(); //show2()的另一种调用方式 Outer.Inner.show2(); } } ~~~ ### 局部内部类 ~~~ /* 局部内部类 A:可以直接访问外部类的成员 B:在局部位置,可以创建内部类对象,通过对象调用内部类方法,来使用局部内部类功能 面试题: 局部内部类访问局部变量的注意事项? A:局部内部类访问局部变量必须用final修饰 B:为什么呢? 局部变量是随着方法的调用而调用,随着调用完毕而消失。 而堆内存的内容并不会立即消失。所以,我们加final修饰。 加入final修饰后,这个变量就成了常量。既然是常量。你消失了。 我在内存中存储的是数据20,所以,我还是有数据在使用。 */ class Outer { private int num = 10; public void method() { //int num2 = 20; //final int num2 = 20; class Inner { public void show() { System.out.println(num); //从内部类中访问本地变量num2; 需要被声明为最终类型 System.out.println(num2);//20 } } //System.out.println(num2); Inner i = new Inner(); i.show(); } } class InnerClassDemo { public static void main(String[] args) { Outer o = new Outer(); o.method(); } } ~~~ ### 匿名内部类(__Android常用) ~~~ /* 匿名内部类 就是内部类的简化写法。 前提:存在一个类或者接口 这里的类可以是具体类也可以是抽象类。 格式: new 类名或者接口名(){ 重写方法; } 本质是什么呢?——对象 是一个 继承了该类 或者 实现了该接口的子类 匿名对象。(该抽象类的具体类、该类的子类、该接口的实现类) */ interface Inter { public abstract void show(); public abstract void show2(); } class Outer { public void method() { /*整个整体仅仅是个 接口的实现类对象 <span style="white-space:pre"> </span>new Inter() { <span style="white-space:pre"> </span>public void show() { <span style="white-space:pre"> </span>System.out.println("show"); <span style="white-space:pre"> </span>} <span style="white-space:pre"> </span>}; <span style="white-space:pre"> </span>*/ //一个方法的时候 /* new Inter() { public void show() { System.out.println("show"); } }.show(); */ //二个方法的时候 /* new Inter() { public void show() { System.out.println("show"); } public void show2() { System.out.println("show2"); } }.show(); new Inter() { public void show() { System.out.println("show"); } public void show2() { System.out.println("show2"); } }.show2(); */ //如果接口中有很多个方法,就非常麻烦了 //改进的方案—— Inter i = new Inter() { //多态 public void show() { System.out.println("show"); } public void show2() { System.out.println("show2"); } }; i.show(); i.show2(); } } class InnerClassDemo { public static void main(String[] args) { Outer o = new Outer(); o.method(); } } ~~~ 再来看一下匿名内部类的具体使用: ~~~ /* 匿名内部类在开发中的使用 */ interface Person { public abstract void study(); } class PersonDemo { //接口名作为形式参数 //其实这里需要的不是接口,而是该接口的实现类的对象 public void method(Person p) { p.study(); } } //实现类——传统方法 class Student implements Person { public void study() { System.out.println("好好学习,天天向上"); } } class InnerClassTest { public static void main(String[] args) { //测试 PersonDemo pd = new PersonDemo(); Person p = new Student(); pd.method(p); System.out.println("--------------------"); //匿名内部类在开发中的使用 //不需要去专门实现一个 实现类 //匿名内部类的本质是继承类或者实现了接口的子类匿名对象 pd.method(new Person(){ //相比上面,简化代码,另外,匿名类用完就是垃圾,就可以立马被回收,所以常在Android中出现。 public void study() { System.out.println("好好学习,天天向上"); } }); } } ~~~
';