15.Java内部类,匿名类学习

1.什么是内部类?

1.1 内部类的定义

《JAVA programming》里这样定义的:
内部类(又叫嵌入类),是一种在其他类的内部定义的类。
如下所示:

public class ShowInnerClass {
    
    private int data;
    public void methodOne(){
        
    }

    /**
     * InnerClass是ShowInnerClass的内部类
     */
    class InnerClass{
        public void method(){
            data++;
            methodOne();
        }
    }
    
}

InnerClass类在ShowInnerClass类的内部定义,所以InnerClass是ShowInnerClass的内部类。

1.2 内部类的特性

内部类作为定义在类中的类,有着其一定的特殊性。

内部类有下列特性:

1.2.1 内部类有外部变量的直接访问权

内部类可以引用包含在它的外部类中的数据和方法,所以不必把外部类的引用传递给内部类的构造方法,基于这个原因,内部类可以使程序简单明了。

如下面所示,内部类InnerClass可以直接访问外部类的私有变量和方法。

public class ShowInnerClass {
    private int data;
    private int num;
    private void methodOne(){
    }
    /**
     * InnerClass是ShowInnerClass的内部类
     */
    class InnerClass{
        public void method(){
            data++;
            methodOne();
        }
    }
}

1.2.2 内部类的编译文件

内部类只是用来支撑外部类的工作。编译后,他的名称形如“外部类名称 内部类名称 . c l a s s ”。例如, s h o w I n n e r C l a s s 中内部类 I n n e r C l a s s , 被编译为 s h o w I n n e r C l a s s 内部类名称.class”。例如,showInnerClass中内部类InnerClass,被编译为showInnerClass 内部类名称.class。例如,showInnerClass中内部类InnerClass,被编译为showInnerClass$InnerClass.class。
在这里插入图片描述

1.2.3 内部类的成员

内部类可以声明为public,protected,private,其意义与用在类的其他成员上相同。

public class ShowInnerClass {
    public ShowInnerClass.InnerClass InnerClass;
    private int data;
    private int num;
    private void methodOne(){
        System.out.println("Hello world");
    }
    public ShowInnerClass(){
        InnerClass = new InnerClass();
    }

    /**
     * InnerClass是ShowInnerClass的内部类
     */
     class InnerClass{
         private int num2;
         protected int age;
         public void method(){
            data++;
            methodOne();
        }
    }
}

1.2.4 静态内部类

内部类可以声明为static的,可以使用外部类的类名来访问静态的内部类,但静态的内部类不能访问外部类的非静态成员。
如果内部类是静态的,使用下列语法可以直接创建它的对象:

外部类.内部类 内部类对象名 = new 外部类.内部类();

示例:

public class StaticInnerClass {

    public static int data;

    private static void methodOne(){
        System.out.println("hello world! ");
    }

    /**
     * InnerClass是ShowInnerClass的内部类
     */
    static class InnerClass{
        private int num2;
        protected int age;
        public void method(){
            data++;
            methodOne();
        }
    }
}

上面的类中定义了一个静态内部类。

public class StaticInnerTest {
    public static void main(String[] args) {
        StaticInnerClass.InnerClass innerClass = new StaticInnerClass.InnerClass();
        innerClass.method();
    }
}

在这里插入图片描述

1.2.5 内部类的使用

我们经常在外部类中创建内部类的对象,但也可以从另外的类中创建内部类的对象。如果内部类是非静态的,必须先创建外部类的实例,然后使用下列语法创建内部类的对象:

外部类.内部类   内部类对象名 = 外部类对象.new 内部类();
public class ShowInnerClass {
    public ShowInnerClass.InnerClass InnerClass;
    private int data;
    private int num;
    private void methodOne(){
        System.out.println("Hello world");
    }

    public ShowInnerClass(){
        InnerClass = new InnerClass();
    }

    /**
     * InnerClass是ShowInnerClass的内部类
     */
     class InnerClass{
         private int num2;
         protected int age;
         public void method(){
            data++;
            methodOne();
        }
    }
}

上面的类中定义了非静态内部类:

public class InnerTest {
    public static void main(String[] args) {
        ShowInnerClass showInnerClass = new ShowInnerClass();
        ShowInnerClass.InnerClass innerClass = showInnerClass.new InnerClass();
        innerClass.method();
    }
}

在这里插入图片描述

2.我们为什么需要内部类?

有人有问题:内部类要实现的东西,用前面已学的东西也可以实现,为什么要用它?
这个问题粗略的来讲可以从使用环境来解释它。有的地方我们用内部类的方法会更方便,至于是那些地方,现在本人并没有很深的理解。
但是,下面的场景我们可以考虑使用:
在定义POJO接收Json数据时,如果存在嵌套结构,我们可以使用内部类来定义接收,如下实例:

public class BackRequest {
    private String transactionId;
    private List<Report> reports;
    public static class Report{
        private String uuid;
        private String errorCode;
        private String errorDesc;
        private String time;
    }
}

使用上面的定义,让我们很容易的将Json数据和实体一一对应。

3.匿名内部类

匿名类就是没有名字的子类。因为没有名字,可以使代码更简洁。。例如
Bank是类,下面代码用Bank的一个子类创建对象:

new Bnak(){
...类体
}

实例:

public class NoNameClass {
    public int num;
    public int age;

    public void say(){
        System.out.println("say hello");
    }

    public static void main(String[] args) {
       NoNameClass noNameClass = new NoNameClass() {
           public void say() {
               System.out.println("I am no body");
           }
       };
       noNameClass.say();
    }
}

在这里插入图片描述

我们可以看出这样使子类的对象的创建更简洁了。但也有一个的局限性,就是一次使用。不能在使用第二次这个类,因为没有名字。

Java基础学习/src/main/java/exa15 · 严家豆/Study - 码云 - 开源中国 (gitee.com)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

程序员小牧之

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值