【Java】接口的细节:成员特点和接口的各种关系

说到成员就是三样东西:成员变量、构造方法、成员方法。


一、成员变量

1)概述

接口中的成员变量只能是 常量默认会使用 public static final 去修饰。

这里默认的意思就是:就算你没写,Java也会帮你加上。为什么是这样的呢?其实是有原因的。

思考:多个子类的共有属性 你觉得它是抽取到哪里的?是抽取到接口当中的吗?

并不是的,多个子类的共有属性 它是抽取到 父类 中的,不会抽取到接口里面。

因此接口中是不会有类似于:name、age等这些成员变量的。

而且接口是一种规则,规则是不能发生改变的。因此接口中的成员变量都是 常量,会使用 final 去修饰。

static 的目的其实就是我可以方便的进行调用,用 接口名.常量名 就行了。

public 表示公共的,表示在所有的地方都可以去使用接口中的常量。


2)其他课程

很多课程中是这样的验证的

System.out.println(Inter.a); // 证明它是用 static 修饰的
Inter.a = 10; // 这里报错,证明它是用 final 修饰的。

我们来查看报错原因:Cannot assign a value to final variable 'a'(无法为最终变量“a”赋值)

image-20240418081645948

这么解释也可以,如果想要看到最本质的情况,那还是需要用到内存分析工具。

接下来就带着大家看一下,这个接口加载到内存后,它到底是什么样的。


3)通过内存分析工具证明

为了掩饰它的效果,这里还需要新建一个 InterImpl,接口的实现类。

Inter.java

package com.itheima.a02interfacedemo2;

public interface Inter {
    // 默认是 public static final 修饰的
    int a = 10;

    // 默认是 public abstract 修饰的
    void method();
}

Inter.java

package com.itheima.a02interfacedemo2;

public class InterImpl implements Inter{
    @Override
    public void method() {
        System.out.println("method");
    }
}

Test.java

package com.itheima.a02interfacedemo2;
import java.util.Scanner;
/*
    成员变量
        只能是常量,默认修饰符:public static final
    构造方法
        没有
    成员方法
        只能是抽象方法,默认修饰符:public abstract
*/
public class Test {
    public static void main(String[] args) {
        //创建实现类对象并调用方法
        InterImpl ii = new InterImpl();
        ii.method();

        // 内存分析工具它有一个前提:程序不能停。
        // 程序一旦执行完毕,就无法通过 内存分析工具 再看它内存中的情况的。
        Scanner sc = new Scanner(System.in);
        sc.next();
    }
}

内存分析工具了解一下就行了,你只需要知道我在干什么就行了。后面会有一个单独的章节去说它的。

接下来执行测试类。

程序开始运行后,点击下面的 Terminal,然后输入 jps,此时我就能看到当前 Test测试类 在运行的时候的 ID。

image-20240418083515441

然后输入 jhsdb hsdb,这样就可以把内存分析工具打开。

image-20240418083433198

File ——> Attach to HotSpot process...Attach:连接;HotSpot:虚拟机的名字)

image-20240418083731552

输入刚刚测试类的ID:21728,然后点击 OK 即可

image-20240418083920279

在这我们不需要去看对象里面是什么东西,如果需要看对象里面有什么,就需要点击 Tool ——> Memory Viewer

但是我现在不想看对象里面,而是想看字节码文件中的信息,那我就点击第一个就行了。Class Browser

image-20240418084106335

在弹出的窗口中,可以去找我们想要的字节码文件,但是太多了。当然也可以在上面的搜索框搜索。

我们这里就来搜 InterImpl 这个实现类,然后回车即可。

可以发现已经找出来了这个实现类。

image-20240418084408447

点击一下,在这可以看见,它有一个 Super Class

Super Class 指的就是它爹,它爹是 Object

image-20240418084837593

再往下,看到 Interfaces,这里就表示这个类实现的所有接口。

但现在我只实现了一个接口:Inter,因此在这里它罗列的就是 Inter

image-20240418084928339

用鼠标点击一下接口,此时它在内存中的一些字节码信息,你就都能看见了。

首先先来看 Fields(属性)。

此时就能很明确的看清:属性是由 public static final 来修饰的,但是我的代码中明没有加上这三个修饰词。

也就是说 public static final 这三个修饰符是Java默认为我们加上的。

image-20240418085313778


二、构造方法

1)概述

构造方法最简单,两个字:没有。

在接口当中,它是没有构造方法的,因为接口不能创建对象,而且接口中也不需要给子类的成员变量去赋值,因此接口用不着构造方法。

既然用不到,Java在设计接口的时候,就没有设计构造方法。


2)通过内存分析工具证明

在通过 内存分析工具 看构造方法之前,先来看一下 InterImpl 这个实现类,这个实现类中我们并没有写构造。

但是 Java 会自动的给它添加一个无参构造。

image-20240418090407245

现在我们就可以通过 内存分析工具 看看这个无参构造长什么样子。

回到 InterImpl 实现类,然后找到 Methods

因为构造方法也是方法,所以它也会罗列在 Methods 里面。

在实现类 InterImpl 的字节码文件中,它有两个方法,第二个方法 method() 就是我们自己重写的 method() 方法。

除此之外还有一个,那就是第一个,这个就是那个 无参构造

此时我们就知道了,如果Java给你添加了 无参构造,此时在 Methods 里面,我是可以用眼睛看到的。

image-20240418090623269

这是我们就可以来看一下在 Inter 接口字节码文件有没有 构造方法

可以看到 Inter 接口字节码文件的 Methods 中只有一个我们自己写的 method() 抽象方法,并没有发现有构造方法。

因此通过这个我们就能清晰的知道,在接口中,是没有构造方法的。

image-20240418091546439


三、成员方法

1)概念

在JDK以前:接口中只能定义抽象方法。默认使用 public abstract 修饰的,就算你没写,Java也会帮你加上。

但是到了JDK和JDK9的时候,Java进行了更新,就可以写有方法体的方法了。

JDK8的新特性:接口中可以定义有方法体的方法

JDK9的新特性:接口中可以定义私有方法。

这两个到后面我们会单独再说,因此我们现在暂时还认为接口中只能写抽象方法即可。


2)通过 内存分析工具 证明

紧接构造方法的证明,可以看见,我们在接口中写的抽象方法,Java也会默认帮你加上 public abstract 修饰词。

image-20240418091512206


四、总结

1、成员变量只能是常量,默认是用 public static final 修饰的。

2、在接口当中是没有构造方法的。

3、在JDK7以前,接口中的成员方法只能是抽象方法,这个方法的前面默认用 public abstract 修饰。

PS:虽然 成员变量成员方法 的修饰符你不写,Java也会帮你加上,但是由于我们现在是属于初学者,这些东西我们暂时先不要省略。等以后牛逼了,那个时候就可以省略了。

  • 25
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值