Java中的内部类

发布时间:2024年01月15日

前言:?

? ? ? ? 我们都已经学过类和方法了,但是没有讲过什么是内部类,那么这一篇我们就来填上最后一个缺口——内部类。

????????当一个事物的内部,还有一个部分需要一个完整的结构进行描述,而这个内部的完整结构又只为外部事物提供服务,那么这个内部完整结构最好使用内部类。

????????在Java中,可以将一个类定义在另一个类或者一个方法的内部,前者称为内部类,后者称为外部类。

????????内部类也是封装的一种体现。

内部类分为:

  1. 实例内部类
  2. 静态内部类
  3. 匿名内部类
  4. 局部内部类。

实例内部类:

? ? ? ? 我们先来看实例内部类。实例内部类中不能定义静态常量和静态方法。

? ? ? ? 此时我们在OuterClass中定义一个InnerClass实例内部类。之后实例化这个内部类,发现报错。

class OuterClass {
    public int data;
    private int data2;
    public static int data3;

    class InnerClass {
        public int data4 = 4;
        //public static int data5 = 5;//报错

        private int data6 = 6;

        public void test() {
            System.out.println("InnerClass::test()");
        }
    }

    public void test() {
        System.out.println("OutterClass::test()");
    }
}

public class Test2 {
    public static void main(String[] args) {
        InnerClass innerClass = new InnerClass();
        //不能够实例化
    }
}

????????也就是说实例内部类不能被直接实例化,但是可以间接实例化。?我们要先实例化外部类,之后通过外部类的对象去初始化外部类中的实例内部类。

OuterClass outerClass = new OuterClass();
OuterClass.InnerClass innerClass = outerClass.new InnerClass();

????????此时我们就能理解为什么实例内部类不能有静态成员了,因为内部类需要外部类引用调用的,而静态成员不需要实例化,可以直接进行使用,所以互相冲突。

????????如果真的需要使用静态,那么可以加上final。

? ? ? ? 如果内部类中有和该外部类中相同的名称的变量成员是,在内部类中访问,优先访问内部类中的成员,也就是说遵循就近原则。

? ? ? ? 如果因为成员名冲突时,要访问外部类的成员,需要使用 外部类的名字.this.成员名进行访问。

? ? ? ? 我们之前说过,一个类就会产生一个字节码文件。那么内部类生成的字节码文件我们执行完代码之后也可以进行查看(在out目录中)。?

? ? ? ? 可以发现内部类的字节码文件名是 外部类 $ 内部类。

静态内部类:

? ? ? ? 顾名思义,就是前面加上了static关键字的内部类。静态内部类只能去调用其外部类中的静态成员或方法。

class Out {
    public int data1 = 1;
    public static int data2 = 2;
    private int data3 = 3;

    static class InClass {
        public int data4 = 4;
        public static int data5 = 5;
        private int data6 = 6;

        public void test() {
            System.out.println(out.data1);
            System.out.println(data2);//只能调用外部类的静态成员或方法
            System.out.println(out.data3);
            System.out.println(data4);
            System.out.println(data5);
            System.out.println("InClass::test()");
        }
    }

    public void test() {
        System.out.println("Out::test()");
    }
}

?????????静态内部类中如果想调用外部类中的非静态成员,则要先初始化一个外部类,之后通过对象引用调用。

? ? ? ? 此时我们就在静态内部类中实例化一其外部类,之后通过外部类的对象去调用里面的非静态成员。

public void test() {
    Out out = new Out();
    System.out.println(out.data1);
    System.out.println(data2);//只能调用外部类的静态成员或方法
    System.out.println(out.data3);
    System.out.println(data4);
    System.out.println(data5);
    System.out.println("InClass::test()");
}

局部内部类:

????????局部内部类:一般在方法中定义,没有什么实际用途。下面代码就是在方法中定义了一个内部类。

public void func() {
    class AA {
        public int a;
    }
    AA aa = new AA();
    System.out.println(aa.a);
}

????????也会生成一个字节码文件。

? ? ? ? 生成了一个Test2$1AA.class字节码文件,命名规则我们不去讨论。

匿名内部类:?

????????匿名内部类一般要使用接口。我们先看代码:

interface IA {
    void test();
}

public class Test2 {
    public static void main(String[] args) {

        new IA() {
            @Override
            public void test() {
                System.out.println("这是重写了接口的方法!");
            }
        };

        IA ia = new IA() {
            @Override
            public void test() {
                System.out.println("这是重写了接口的方法!");
            }
        };
    }
}

? ? ? ? 这里先写了一个接口,之后通过Test2直接定义了一个匿名内部类(我也不知道名字别问我),之后重写接口中的方法,最后通过向上转型动态绑定调用重写方法。

? ? ? ? 博主无能,不清楚内部类的作用,希望大佬能说一下。?

文章来源:https://blog.csdn.net/weixin_64132124/article/details/135605148
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。