【Java】认识内部类

为什么要学习内部类,这是有原因的,因为内部类是类的五大成员之一。

类的五大成员:属性(就是我们之前讲的name、age这样的成员变量)、方法(就是我们之前所说的行为,例如 eat() 方法等等)、构造方法(在创建对象的时候使用到的)、代码块、内部类。


一、什么是内部类?

内部类(Inner Class):在一个类的里面,再定义一个其他的类,这个其他的类就称之为内部类

例如:在A类的内部定义B类,B类就被称为内部类。

例如下图代码中,Outer就被称之为 外部类Inner 被称之为 内部类。与此同时,跟这两个类都无关的所有的类,我们都统称为:外部其他类。

所以说在以后,我们就可以在 外部其他类 中去创建 内部类 的对象,并调用它的方法。

image-20240418184842103


二、为什么要学习内部类?

需求:写一个Javabean类描述汽车。

属性:汽车的品牌,车龄,颜色,发动机(engine)的品牌,使用年限。

有的同学肯定觉得想都不用想,直接定义一个 Car类 就行了,并在成员位置定义题目中的属性即可。

image-20240418185051018

这种写法乍看上去没有什么问题,但是细品,这个里面的发动机,它是一个独立的个体,跟车本身其实还是有点区别的。

所以说,跟发动机相关的属性,我们不应该跟车定义在一起,那该怎么办呢?

有的同学又会想:那这个简单,我再定义一个发动机的类(Engine)不就ok了吗?

是的,你说的没错,但是还不够,因为发动机是需要依赖车才能存在的,发动机如果单独出现,它其实是没有什么实际意义的。

image-20240418185403828

因此最好的解决方案就是把发动机 Engine类 定义在 Car类 的里面,这样就满足要求了。

这样就表示:车里面有发动机,而发动机又是一个独立的个体。

此时,Car 就是 外部类Engine 就是 内部类

image-20240418190231605

三、内部类的使用

我们以后在定义内部类的时候,一般会遵守这样的规则:

  • 内部类表示的事物是外部类的一部分
  • 内部类单独出现没有什么实际的意义

内部类的访问特点

  • 内部类可以直接访问外部类的成员,包括私有
  • 但是外部类不能直接访问内部类的成员。如果外部类要访问内部类的成员,必须要创建对象

四、代码示例

1)需求

写一个Javabean类描述汽车。
属性:汽车的品牌,车龄,颜色,发动机的品牌,使用年限。

内部类的访问特点:
	内部类可以直接访问外部类的成员,包括私有
    外部类要访问内部类的成员,必须创建对象

2)代码示例

技巧:右击 Test.java ,然后点击 Split and Move Right,将它移动到右边去。

image-20240418191147627

一左一右方便观看。

image-20240418191318111

以下的代码可以按注释的顺序观看。

Test.java

package com.itheima.a01innerclassdemo1;

public class Test {
    public static void main(String[] args) {
        Car c = new Car();
        c.carName = "宾利";
        c.carAge = 1;
        c.carColor = "粉色";

        c.show();
    }
}

Car.java

package com.itheima.a01innerclassdemo1;

public class Car {
    privateString carName;
    int carAge;
    String carColor;

    // 5.这是因为,在外部其他类中创建Car对象,然后调用show()方法时,方法里面其实是有一个隐藏的 this,这个this在当前方法被调用的时候,虚拟机会把调用者的地址值赋值给这里的this。
    public void show(Car this){
        // 3.在外部类的 show() 方法中,如果你获取的是外部类的成员,一点问题都没有
        // 6.因此,如果我们在方法中直接调用成员变量的话,前面也有一个隐含的this。
        // 7.此时虚拟机就知道了,这里的this.carName是打印调用者车的名字:宾利
        System.out.println(this.carName);
        
        // 4.但是,如果你想要获取内部类的,它就会直接报错
        // 8.这个时候就需要思考:在代码中,有没有发动机的对象呢?是没有的
        // 既然没有发动机的对象,这里的engineName就不知道打印什么了,导致代码报错
        System.out.println(e.engineName);
 
        // 因此,如果外部类要访问内部类的成员,必须要创建内部类的对象,然后再使用这个对象去调用engineName
        Engine e = new Engine();
        System.out.println(e.engineName);
    }


    class Engine{
        String engineName;
        int engineAge;

        public void show(){
            // 1.使用本类中的变量是没有问题的
            System.out.println(engineName);
            // 2.内部类使用外部类的成员变量也是没有问题的
            // 尽管外部类的成员变量是用private修饰的,也是可以正常调用的
            System.out.println(carName);
        }
    }
}

五、内部类该如何使用呢?

1)IDEA图标

接下来带大家看一段Java的源代码,就知道如何使用了。

ctrl + N,搜索 java.util 中的 ArrayList 类。

image-20240418192640218

此时它就会跳转到 ArrayList 的源码。

然后按快捷键 ctrl + F12,这是就会出现 ArrayList 中所有的成员消息的列表。


下面 C 是蓝色的,是 class 的首字母,这就表示后面的 ArrayList 是类名

image-20240428150155644


像这种,前面是粉红色的,里面是 m 的图标(method),表示这个是方法。例如 add() 方法。

有构造方法也有成员方法。如果方法名跟类名一样,就表示是构造方法,而方法名跟类名不一样,那就是普通的成员方法。

image-20240428150453174

细节1

image-20240428152038305

细节2:有的方法在后面,有这种灰色的字体,字体的前面有这种向上的小箭头,或者是向右的小箭头。

向上的箭头:表示重写父类 / 接口中的方法,在 的后面就标记了父类 / 接口的名称。

因此这个整体就可以这么去理解:add 方法是重写了父类 AbstractList 中的方法。

还有的方法本身就是灰色的:如果我们用鼠标点击这个灰色的方法,它就会跳转到 AbstractList 接口中,相当于这个方法是继承了 AbstractList 里面的方法

因此 表示这个方法是重写的; 表示这个方法来自于哪个类 / 接口

image-20240428151614225


如果说,它前面的图标是这种黄色的,里面是 f 的图标,表示的是属性(成员变量 / 常量),f 指的是 field

image-20240418193243818

点进来就是一个属性(成员变量)。

image-20240418193332878

绿色的 I 表示 interface,接口名叫 Entry,这个接口来自于 Map 集合中

image-20240428151844440


再往下,它前面的图标是这种蓝色的,里面是 c 的图标,这个就表示它是 ArrayList 的内部类。

可以发现,在 ArrayList 中有很多的内部类。

image-20240418193425939

现在要给大家介绍的是第二个:Itr


2)Itr 内部类

首先我们要知道,ArrayList 是一个集合,集合的作用就是帮助我们来存储元素的,我们可以把数据往集合里面放,并且可以通过遍历的方式,将数据从集合中获取出来。

但是 ArrayList 的遍历方式有很多很多种,在之前,我们仅仅是用最简单的for循环进行了遍历。

除了for循环的遍历方式外,还有很多的遍历方式。

这里我们看到的 Itr(iteration),专业叫做 迭代器,这个就是一种相对比较高级的遍历方式。

这种遍历方式,相对集合来讲,是相对独立的,但是它又属于集合,所以Java就把 迭代器 这个类,设计成了 ArrayList 的内部类。

你要来想,如果集合都没有,那我们遍历个毛啊,它不能单独出现,一定要有集合,才能有迭代器。

这个就是 内部类 在实际中的应用。

image-20240418194129530


六、总结

1、什么是内部类?

写在一个类里面的类就叫做内部类。

2、什么时候用到内部类?

如果B类表示的事物是A类的一部分,而且B类单独存在没有意义,这个时候我们就可以把B类设计成A类的内部类。

比如:汽车的发动机,ArrayList的迭代器,人的心脏等等。这里的发动机、迭代器、心脏,都是属于其他类的一部分,并且它们自己单独存在是没有意义的,所以我们可以把它们设计成内部类。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值