当前位置:   article > 正文

Java面向对象(高级)-- 接口(interface)_java接口对象

java接口对象

一、概念

(1)引入

从三条主线的角度来说的话,这儿属于第三条主线,叫做interface关键字的使用。

从另外一个角度来说的话,它是跟类并列的一个结构,这样讲的话,它的地位一下子就提升了。

可以看一下API

比如说就看一下这个long包下的base。这些结构里边,我们再来看一下这个long包:

image.png

可以看到Interface和Class是并列的结构:

image.png

平常新建java文件的时候,也可以看到类与接口:

image.png

那这个接口到底是一个什么样的结构?跟类并列的是吧?前面我们讲的面向对象特征说类里边都能声明什么,其实都是类的,这个体系跟接口没关系

(2)类比

生活中大家每天都在用USB接口,那么USB接口与我们今天要学习的接口有什么相同点呢?

USB,(Universal Serial Bus,通用串行总线)是Intel公司开发的总线架构,使得在计算机上添加串行设备(鼠标、键盘、打印机、扫描仪、摄像头、充电器、MP3机、手机、数码相机、移动硬盘等)非常容易。

其实,不管是电脑上的USB插口,还是其他设备上的USB插口都只是遵循了USB规范的一种具体设备而已。

image.png

只要设备遵循USB规范的,那么就可以与电脑互联,并正常通信。至于这个设备、电脑是哪个厂家制造的,内部是如何实现的,我们都无需关心。

Java的软件系统会有很多模块组成,那么各个模块之间也应该采用这种面向接口低耦合,为系统提供更好的可扩展性和可维护性。


接口用interface这个关键字去修饰,就好比类用class来修饰是一样的。首先,要想理解接口,我们先跟生活中的一个例子做一个类比。

生活当中,我们通常提到这个USB,通常就会说USB接口。其实这块呢,就提到了接口这个词,那么这个USB接口跟我们现在讲的这个接口是不是一个概念呢?其实还真可以理解成就是一个概念。

生活当中,大家每天都在用USB接口,首先看USB,它叫通用串行总线。在电脑上,有一个或者有多个USB的接口,我们就可以跟很多外部设备进行连接了。

连接上以后的话,跟电脑就可以进行数据的传输了,这就是我们所谓的USB接口,你会发现全世界的USB接口的标准都是一样的。
比如说里边有几个金属点啊,这个尺寸是什么样子的,全都是一样的,所以我们都可以去做连接。

那么这其实就涉及到了一个USB的规范问题。具体的,不管是英特尔也好,或者它又交给了哪个组织也好,这个组织的话,就来负责制定USB的这个规范。

这个规范呢,咱们作为普通人,能够看到的就是一个长啊宽啊,或者里边有几个金属点(进行数据传输),这都是面儿上能看到的。
那没有看到,其实里边,就会涉及到很多功能的一些规范。

然后要求所有的外部设备,都应该具备相关的一些功能,比如说一连接上电脑以后能够进行,比如电脑对外开放了USB,连接上它以后,首先有提示“可以进行数据传输”了,包括所有的外部设备,我们最后不用的时候,这块儿有对应的弹出。

传输的时候,都会有相应的一些方法的支持。像这些的话,其实都是一些对应的规范,这个规范,在USB这个规范里面,它就定义好了。要求这些外部设备都得去实现。

其实这里边,提到这个USB接口就是我们现在要讲的这样的一种接口的概念,其实是类似的。
那我们这块儿来看一看JAVA当中这个接口是什么意思,回头让大家比对一下,你就知道,其实确实差不多。

(3)举例

接口就是规范,定义的是一组规则,体现了现实世界中“如果你是/要…则必须能…”的思想。继承是一个"是不是"的is-a关系,而接口实现则是 "能不能"的has-a关系。

1. 举例1

电脑都预留了可以插入USB设备的USB接口,USB接口具备基本的数据传输的开启功能和关闭功能。你能不能用USB进行连接,或是否具备USB通信功能,就看你能否遵循USB接口规范。
image.png

比如说图中这个电脑,一个相机、打印机,或者这个U盘,现在想跟电脑进行数据库的传输。

那么,你现在是有没有啊?你要是想进行数据传输了,你能不能有这样的一个规范,这样一个标准呢去遵循呢?如果你遵循了这样的标准了,那我就让你跟电脑进行数据传输;你要没有遵循这个标准,我就不让你进行数据的传输。

所以这个标准的话,就体现为JAVA层面的一个接口,就是可以定义一个接口,假设就叫USB。然后要求、几个设备都得遵循这个规范,这个遵循怎么体现呢?

注意不是继承了,不能说这个打印机的父类是一个USB是吧?那这时候就涉及到类和这个USB接口之间的关系,我们称为实现关系一旦实现了这个USB接口,它就具备了这个规范里边定义的一些功能

2. 举例2

再比如说这里,篮球运动员、足球运动员,大学生、小学生。篮球足球他们继承于叫运动员的类,学生这块儿继承学生类,这个是现有的继承关系
image.png

现在有一个叫学英语这样的一个接口,这个接口它封装了一定的功能,或者说这个接口定义了学英语的一些规范。

比如说让足球运动员,大学生,不管是谁,如果你们想学英语,想遵循这样的一个接口的规范,你就实现这个接口就可以了。这是我们用的这个关系叫实现

实现以后,足球运动员和大学生,他们就能够去学英语了。父类该是谁还是谁,不受影响。

3. 举例3

再比如,看下面的图:
image.png

这个飞机也好,子弹也好,风筝也好,热气球也好,这块儿都是不同场景的具体的类。

这呢,我们只考虑实现的关系。

现在呢,有一个接口,它表示的就是可以飞这样的功能,或者叫规范,我们定义到这个接口里了。

然后你发现飞机也好,子弹也好,风筝也好,热气球,它们都可以飞,那我就可以让它们去实现这个接口。或者换句话说,当你实现这个接口以后,体现为就是你们可以飞了

然后这还有一个接口叫攻击性,其实可以看到这里都不是名词了,以前讲父类的话,其实都是一个具体的载体,是一个名词,现在都是一种功能的封装。

这个子弹具备攻击性,那我就让子弹也实现这个接口,实现这个接口以后,它就具备了这样的一个功能。

所以从这个角度来讲呢,实现接口跟上一个例子继承的父类,它确实是不同场景。

4. 举例4

刚才提到了规范的问题,只要你实现了这个规范,你就具备这个规范里边定义的一些相关的功能

那么关于规范这个事儿,再唠叨两句,怎么体现叫规范呢?

刚才我们也说了,USB呢是定义了跟电脑通信的一种规范。谁实现了这个规范,谁就能够跟电脑进行数据传输。
这块呢又举了个例子。

这个例子的话,是在讲完这个java基础以后,大家可以学的一门技术,叫做jdbc,什么叫jdbc呢?它实际上是一波api。说白了就是一些类库,这个类库里边,主要的就是接口。

那这个接口是干什么用的呢?它就是规范了我们用JAVA程序操作不同数据库的一组规范

以前的话,比如没有JDBC,直接用JAVA程序去操作具体的数据库就可以了,但是这样写程序的话,会不具备通用性。像MySQL跟Oracle是不同的数据库,可能这个细节差别很大,你用JAVA程序连的MySQL,再拿这个代码去连Oracle肯定不好使。所以需要重新再去写一套代码去连Oracle,包括这个DB2也同样的道理。

显然就感觉一致性很差,怎么办呢?现在Sun公司他出面定一套标准,这套标准呢,就是有好多的接口,那么这套标准合在一起就叫做JDBC,所以对于JAVA程序员来讲,你不要去面向具体的数据库去编程了,你只面向我这套接口编程就行。需要具备什么样功能,我这都定义好了,你直接去实现我这个接口,实现完以后的话,再去提供下边这些实现类。

因为是面向接口编程的,它封装了不同数据库厂商的细节。

比如现在操作的是Oracle,后期想改成MySQL,其实这块儿呢,非常简单,因为不同的数据库厂商都针对这套接口,就是这个标准进行了相关的一些改造了,都满足这套标准了。然后在连接MySQL的时候,这个代码其实变动很小,直接就可以来操作MySQL。

这就使得代码具备很好的移植性。

这就体现了接口它的作用,它就是一套规范
image.png

Java程序是否能够连接使用某种数据库产品,那么要看该数据库产品能否实现Java设计的JDBC规范。

接口的本质是契约、标准、规范,就像我们的法律一样。制定好后大家都要遵守。

比如制定了JDBC这样一套规范,里边主要是接口大,大家都遵循这套接口和规范。那我们再去编程的时候,这个代码就具备一致性、规范性。

USB也同样道理,全世界范围内USB的标准全是一样的,大家都去遵守。你去欧洲买USB的一个设备插到你电脑上照样也能用,因为这个标准都是一样的。

(4) 定义格式及重点举例

接口的定义,它与定义类方式相似,但是使用 interface 关键字。它也会被编译成.class文件,但一定要明确它并不是类,而是另外一种引用数据类型。

引用数据类型:数组,类,枚举,接口,注解。

1. 接口的声明格式

[修饰符] interface 接口名{
    //接口的成员列表:
    // 公共的静态常量
    // 公共的抽象方法
    
    // 公共的默认方法(JDK1.8以上)
    // 公共的静态方法(JDK1.8以上)
    // 私有方法(JDK1.9以上)
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

示例代码:

package com.atguigu.interfacetype;

public interface USB3{
    //静态常量
    long MAX_SPEED = 500*1024*1024;//500MB/s

    //抽象方法
    void in();
    void out();

    //默认方法
    default void start(){
        System.out.println("开始");
    }
    default void stop(){
        System.out.println("结束");
    }

    //静态方法
    static void show(){
        System.out.println("USB 3.0可以同步全速地进行读写操作");
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23

2. 接口的成员说明

在JDK8.0 之前,接口中只允许出现:

(1)公共的静态的常量:其中public static final可以省略

(2)公共的抽象的方法:其中public abstract可以省略

理解:接口是从多个相似类中抽象出来的规范,不需要提供具体实现

在JDK8.0 时,接口中允许声明默认方法静态方法

(3)公共的默认的方法:其中public 可以省略,建议保留,但是default不能省略

(4)公共的静态的方法:其中public 可以省略,建议保留,但是static不能省略

在JDK9.0 时,接口又增加了:

(5)私有方法

除此之外,接口中没有构造器,没有初始化块,因为接口中没有成员变量需要动态初始化。

3. 接口内部结构的说明

<1> 接口的理解:接口的本质是契约、标准、规范,就像我们的法律一样。制定好后大家都要遵守。

<2> 定义接口的关键字interface

<3> 接口内部结构的说明

  • 可以声明:

    • 属性:必须使用public static final修饰(全局常量–不能改),不能声明变量。

    • 方法

      • jdk8之前:声明抽象方法,修饰为public abstract
      • jdk8:声明静态方法、默认方法(自己用的少,一般源码会用)
      • jdk9:声明私有方法(自己用的少,一般源码会用)
  • 不可以声明:构造器、代码块等(接口跟抽象类一样也不能造对象,接口压根没有构造器)

4. 举例

image.png

4.1 举例1–接口

属性

public class InterfaceTest {
    public static void main(String[] args) {
        System.out.println(Flyable.MIN_SPEED);  //可以直接拿结构调用

        System.out.println(Flyable.MAX_SPEED);  //就算MAX_SPEED前面没有写static,也可以调用

        //Flyable.MAX_SPEED=7000;   //报错,MAX_SPEED是常量
    }
}

interface Flyable{  //接口
    //1.全局常量
    public static final int MIN_SPEED=0;      //能飞行的最低速度

    //public static final可以不写
    int MAX_SPEED=7900;   //能飞行的最高速度

}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18

final体现也可以证明,比如修改它的值,会报错,如下:

image.png

由于属性一般有 public static final 声明,所以可以省略。

方法

interface Flyable{  //接口

    //2.方法(JDK8之前,只能写抽象方法)
    //可以省略 public abstract 声明
    public abstract void fly();

}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

由于抽象方法一般都有 public abstract声明,所以可以省略。

4.2 举例2–类实现接口

再比如“攻击性”。

interface Attackable{   //接口
    public abstract void attack();
}
  • 1
  • 2
  • 3

现在来提供具体接口的实现类

类实现接口之后,接口里面的属性、方法也都拿过来了。

class Plane implements Flyable{

}
  • 1
  • 2
  • 3

目前会报错,如下:

image.png

报错的原因是因为接口的抽象方法,两方面处理,要么写成一个抽象类,要么就将抽象方法实现以下。

比如:

//方法一、抽象类
abstract class Plane implements Flyable{

}

//方法二、重写抽象方法
class Bullet implements Flyable{

    @Override
    public void fly() {

    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13

若将抽象方法实现了,相对应就可以实例化了

我们也可以实现两个接口,同样会拥有它们所有的抽象方法,都需要重写,比如:

//重写抽象方法
class Bullet implements Flyable,Attackable{

    @Override
    public void fly() {

    }

    @Override
    public void attack() {

    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13

那么后续操作就和以前一样了,比如可以通过类造对象并调方法。比如:

package yuyi01;

/**
 * ClassName: InterfaceTest
 * Package: yuyi01
 * Description:
 *
 * @Author 雨翼轻尘
 * @Create 2023/11/26 0026 9:22
 */
public class InterfaceTest {
    public static void main(String[] args) {
        System.out.println(Flyable.MIN_SPEED);  //可以直接拿结构调用

        System.out.println(Flyable.MAX_SPEED);  //就算MAX_SPEED前面没有写static,也可以调用

        //Flyable.MAX_SPEED=7000;   //报错,MAX_SPEED是常量

        Bullet b1=new Bullet();
        b1.fly();
        b1.attack();
    }
}

interface Flyable{  //接口
    //1.全局常量
    public static final int MIN_SPEED=0;      //能飞行的最低速度

    //public static final可以不写
    int MAX_SPEED=7900;   //能飞行的最高速度


    //2.方法(JDK8之前,只能写抽象方法)
    //可以省略 public abstract 声明
    public abstract void fly();

}

interface Attackable{   //接口
    public abstract void attack();
}

//抽象类
abstract class Plane implements Flyable{

}

//重写抽象方法
class Bullet implements Flyable,Attackable{

    @Override
    public void fly() {
        System.out.println("让子弹飞一下");
    }

    @Override
    public void attack() {
        System.out.println("子弹可以击穿石头");
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60

输出结果:

image.png


本文内容由网友自发贡献,转载请注明出处:【wpsshop博客】

推荐阅读
相关标签