过年无聊吧java的内部类复习了一下,把学习的总结拿出来分享,也当时做个备份,以便日后查阅
一、演示内部类定义在成员位置上
- /**
- * 一、演示内部类定义在成员位置上
- * */
- public class InnerDemo1 {
- //成员变量
- int num = 8;
- //定义一个内部类
- class Inner{
- //内部类中的一个方法
- void show(){
- System.out.println(num);
- }
- }
- /**
- * 创建内部类调用其方法
- */
- public static void main(String[] args) {
- /*
- * 创建内部类的格式
- * 外部类名.内部类名 对象名 = 外部类对象.内部类对象
- */
- // 使用Inner直接引用内部类也可以,但是最好用(外部类名.内部类名)的方式,便于区分同名的内部类
- // Inner inner = new InnerDemo1().new Inner();,
- InnerDemo1.Inner inner = new InnerDemo1().new Inner();
- inner.show();//调用show()方法。
- }
- }
二、演示内部类中访问变量的方式
- /**
- * 二、演示内部类中访问变量的方式
- * */
- public class InnerDemo2 {
- //外部类中的成员变量
- int num = 8;
- class Inner{
- //内部类的成员变量
- int num = 7;
- void show(){
- //内部类的局部变量
- int num = 6;
- System.out.println(num);//6 不指定所属,则指向的是该方法中局部的同名变量
- System.out.println(this.num);//7 this代表内部类,指向的用于指定内部类的成员变量
- System.out.println(InnerDemo2.this.num);//8 外部类名.this.变量名,指向的是外部类的成员变量
- }
- }
- public static void main(String[] args) {
- InnerDemo2.Inner inner = new InnerDemo2().new Inner();
- inner.show();
- }
- }
三、演示静态内部类
- /**
- * 三、演示静态内部类
- * */
- public class InnerDemo3 {
- /*
- * 静态内部类访问的外部类的成员变量也要试静态的。
- * 即静态内部类只能访问外部类的静态成员
- */
- static int num = 8;
- /**静态内部类*/
- static class Inner{
- /**非静态方法*/
- void show(){
- System.out.println(num);
- }
- /**静态方法*/
- static void run(){
- System.out.println("Inner calss method run");
- }
- }
- public static void main(String[] args) {
- /*
- * 创建静态内部类的格式
- * 外部类名.内部类名 对象名 = new 外部类名.内部类名();
- */
- InnerDemo3.Inner inner = new InnerDemo3.Inner();
- //调用非静态方法
- inner.show();
- //调用静态方法
- // inner.run();
- InnerDemo3.Inner.run();//直接通过类名调用
- }
- }
四、演示匿名内部类
- /**
- * 四、演示匿名内部类
- * 匿名内部类就是没有名字的内部类
- * 好处:简化了内部类的书写。
- * 前提:内部类必须要继承或者实现一个外部类或外部接口
- *
- */
- interface MyInterface{
- void show();
- }
- public class AnonymousClassDemo1 {
- /**
- * 创建匿名内部类并调用其方法
- * new MyInterface(){...}创建的是接口的实现类,即子类
- * */
- public static void method(){
- //创建一个MyInterface接口的匿名内部类,覆盖其为实现的方法,并调用其方法
- new MyInterface(){
- @Override
- public void show() {
- System.out.println("show");
- }
- }.show();
- }
- /**
- * 使用接口引用该匿名内部类
- * 父类引用子类对象
- * */
- public static void method2(){
- //创建一个MyInterface接口的匿名内部类,覆盖其为实现的方法,并起个名字
- MyInterface inter = new MyInterface(){
- @Override
- public void show() {
- System.out.println("show2");
- }
- };
- //调用show方法
- inter.show();
- }
- /**
- * 在匿名内部类中添加新方法
- */
- public static void method3(){
- new Object(){
- //添加子类特有的方法
- void run(){
- System.out.println("run");
- }
- }.run();
- }
- /**
- * 内部类的错误使用
- * */
- public static void method4(){
- Object obj = new Object(){
- //添加子类特有的方法
- void run(){
- System.out.println("run");
- }
- };
- //编译不通过,Object中找不到run()方法
- // obj.run();
- }
- /**
- * 内部类的应用
- * 使用内部类来调用覆盖后的方法
- */
- public static void method5(){
- Object obj = new Object(){
- @Override
- public String toString() {
- String s = "覆盖了Object中的toString方法";
- return s;
- }
- };
- //调用覆盖后的toString方法
- System.out.println(obj.toString());
- }
- /**
- * 内部类访问局部变量
- * 为什么用final修饰局部变量?
- * 简单说就是因为局部内部类是在内存栈中,方法执行完局部变量就会出栈,
- * 而局部内部类还持有局部变量的引用,jvm就会出现异常,这和jvm的设计
- * 有关,在底层会把final修饰的局部变量在方法执行完复制一份到内部类
- * 中继续保留对该变量的引用。
- *
- */
- public static void method6(final int a){
- final int b = 9;
- new Object(){
- /**
- * 局部内部类中访问的方法参数要用final修饰
- */
- void show(){
- System.out.println(a);
- }
- /**
- * 局部内部类中访问的局部变量要被final修饰
- */
- void add(){
- System.out.println(a+b);
- }
- };
- }
- public static void main(String[] args) {
- method();
- method2();
- method3();
- method4();
- method5();
- }
- }
五、内部类面试题
- /**
- * 五、内部类面试题
- * 给出一个接口Inter,要求Outers.method().show();能执行,
- * 要求补全Outers类中的代码用匿名内部类
- * interface Inter{
- void show();
- }
- class Outers{
- //TODO
- }
- public static void main(String[] args) {
- Outers.method().show();
- }
- *
- */
- interface Inter{
- void show();
- }
- class Outers{
- static Inter method(){
- return new Inter(){
- @Override
- public void show() {
- System.out.println("hello");
- }
- };
- }
- }
- public class InnerTest {
- public static void main(String[] args) {
- Outers.method().show();
- /*
- *分析:
- * 1: Outers.method()说明method()是静态的。
- * 2: Outers.method().show();说明调用method方法返回的是Inter接口的子类对象
- */
- }
- }