14-内部类介绍

内部类

什么是内部类

就是在一个类的里面, 再定义一个类
举例就是再 A 类的内部定义 B 类, B 类就被称为内部类

image.png

类似结构体里面加入结构体, 日期里面加入生日类
image.png

内部类的特点

内部类的访问特点:

内部类可以直接访问外部类的成员,包括私有.

public class car {
    String carName;
    int carAge;
    String carColor;

    class Engine {
        String engineName;
        int engineAge;

        public void show() {
            System.out.println(engineAge);
            System.out.println(carName);
        }
    }

    public void show() {
        System.out.println(carAge);
    }
}

外部类要访问内部类的成员,必须创建对象
B 类表示的事物是 A 的一部分, 且 B 单独存在没有意义

什么时候用到内部类

B 类表示的事物是 A 的一部分, 且 B 单独存在没有意义
比如, 汽车的发动机, Arraylist 的迭代器, 人的心脏

成员内部类

写在成员位置的,属于外部类的成员。所以它和外部类的成员一眼都可以被各种修饰符所修饰
成员内部类可以被一些修饰符所修饰,比如: private,默认, 默认只能被本包的使用, protected, public,static 等
这里创建成员内部类就可以类比于类中创建一个新成员
在成员内部类里面,JDK 16 之前不能定义静态变量,JDK 16 开始才可以定义静态变量

public class demo8 {
    class group {
        static int num;
        static String name;
    }
}
JDK17之后的版本这段代码是不报错的

获取成员内部类对象的两种方式

方式 1: 外部类编写方法,对外提供内部类对象, 一般是私有内部类才会这样用, 其他情况下用方式 2
这中方式类似与 getName,setName, 我们自己提供接口
方式 2: 直接创建
格式: 外部类名. 内部类名对象名 = 外部类对象. 内部类对象
范例: Outer. Inner oi = new Outer ( ). New Inner ();

对这个代码的解释
我们知道这个内部类其实相当于这个外部类的一个成员,成员是不能单独的去使用创建的,比如说你想调用这个car类中的name,那么你不可以直接去调用,而是要去先创建一个car对象,然后再去调用姓名
操作如下
car c = new car();
System.out.println(c.carName);
简化写法是System.out.println(new car().carName);
同理可以推出,如果我们想要调用这个Inner内部类,我们也是要创建外部对象
new car().new Inner()
因为这个Inner不是一个变量,而是一个对象所以用new

image.png

如果内部类变量是私有的, 我们在外界不能直接调用构建, 我们可以在外部类里面定义一个接口, 通过这个接口我们可以实现这个内部类
image.png

image.png

默认的类型, 我们可以在本包里面用, 在其他包里面不能用
Public 类型, 在什么地方都能用
image.png
内部类里面有一个隐藏的 Outer this 变量, 这个变量存放这个外部类的地址, 如果只是用 this 的话, 调用的是这个堆的内存, 如果是 outer this 的话调用的就是这个外部类的信息.

静态内部类

image.png
静态内部类只能访问外部类中的静态变量和静态方法
调用静态的方法,这个静态的方法不属于对象,虽然我们也可以通过对象进行调用,但是不推荐,我们可以通过外部类名.内部类名.方法名 ( );

image.png
因为是静态的, 所以我们在调用的时候不需要先创建外部类的对象, 而是直接通过类名来进行调用

// 外部类:Outer01
class Outer01{
    private static  String sc_name = "黑马程序";
    // 内部类: Inner01
    public static class Inner01{
        // 这里面的东西与类是完全一样的。
        private String name;
        public Inner01(String name) {
            this.name = name;
        }
        public void showName(){
            System.out.println(this.name);
            // 拓展:静态内部类可以直接访问外部类的静态成员。
            System.out.println(sc_name);
        }
    }
}

public class InnerClassDemo01 {
    public static void main(String[] args) {
        // 创建静态内部类对象。
        // 外部类.内部类  变量 = new  外部类.内部类构造器;
        Outer01.Inner01 in  = new Outer01.Inner01("张三");
        in.showName();
    }
}

局部内部类

  1. 将内部类定义在方法里面就叫做局部内部类,类似于方法里面的局部变量。我们就可以把它当作局部变量来进行理解
  2. 外界是无法直接使用,需要在方法内部创建对象并使用。
  3. 该类可以直接访问外部类的成员,也可以访问方法内的局部变量。
  4. 方法里新建内部类对象这个和静态内部类不一样, 我们直接用 new 进行创建就可以了

image.png

匿名内部类

匿名内部类本质上就是隐藏了名字的内部类
格式

new 类名或者接口名() {
     重写方法;
};
interface Swim {
    public abstract void swimming();
}

// 1. 定义接口的实现类
class Student implements Swim {
    // 2. 重写抽象方法
    @Override
    public void swimming() {
        System.out.println("狗刨式...");
    }
}

public class Test {
    public static void main(String[] args) {
        // 3. 创建实现类对象
        Student s = new Student();
        // 4. 调用方法
        s.swimming();
    }
}

image.png
匿名内部类就是我们用来实现接口的一种东西
image.png
后面的大括号包围的是一个内部类, 这个内部类是没有名字, 这个内部类实现了接口, 或者是继承类
如果前面是接口那么就是实现接口, 如果前面是类, 那么就是实现类.
image.png
当我们有一个类只用一次的时候我们如果建立类的话太浪费了, 我们可以采用匿名内部类的方法.

image.png

image.png
匿名内部类并不是没有名字, 只是不需要你取名字, 会用 Test$num 来命名, 系统自动命名的
我们可以通过找到字节码之后用 ctrl+p 进行反编译

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值