【Java】面向对象之——接口的理解

简介: 【Java】面向对象之——接口的理解

image.png

【Java】面向对象之——接口的理解

🎄语法规则

🎄实现多个接口

🎄接口使用实例

🎄接口之间的继承

🎄Cloneable 接口和深浅拷贝

🎄总结

接口是抽象类的更进一步. 抽象类中还可以包含非抽象方法, 和字段. 而接口中包含的方法都是抽象方法, 字段只能包含静态常量.


有时必须从几个类中派生出一个子类,继承它们所有的属性和方法。但是,Java不支持多重继承。有了接口,就可以得到多重继承的效果。


接口(interface)是抽象方法和常量值的定义的集合。

从本质上讲,接口是一种特殊的抽象类,这种抽象类中只包含常量和方法的定义,而没有变量和方法的实现。


🎄语法规则

在打印图形的示例中, 我们的父类 Shape 并没有包含别的非抽象方法, 也可以设计成一个接口

image.png

image.png

代码解释:


使用 interface 定义一个接口

接口中的方法一定是抽象方法, 因此可以省略 abstract

接口中的方法一定是 public, 因此可以省略 public

Cycle 使用 implements 继承接口. 此时表达的含义不再是 “扩展”, 而是 “实现”

在调用的时候同样可以创建一个接口的引用, 对应到一个子类的实例.

接口不能单独被实例化.

扩展(extends) vs 实现(implements)

扩展指的是当前已经有一定的功能了, 进一步扩充功能.

实现指的是当前啥都没有, 需要从头构造出来.


接口中只能包含抽象方法. 对于字段来说, 接口中只能包含静态常量(final static)


image.png

其中的 public, static, final 的关键字都可以省略.省略后的 num 仍然表示 public 的静态常量.


提示:


我们创建接口的时候, 接口的命名一般以大写字母 I 开头.

接口的命名一般使用 “形容词” 词性的单词.

阿里编码规范中约定, 接口中的方法和属性不要加任何修饰符号, 保持代码的简洁性.

image.png

image.png

🎄实现多个接口

有的时候我们需要让一个类同时继承自多个父类. 这件事情在有些编程语言通过 多继承 的方式来实现的.

然而 Java 中只支持单继承, 一个类只能 extends 一个父类. 但是可以同时实现多个接口, 也能达到多继承类似的效果.

现在我们通过类来表示一组动物.


image.png

另外我们再提供一组接口, 分别表示 “会飞的”, “会跑的”, “会游泳的”.

image.png

接下来我们创建几个具体的动物

猫, 是会跑的.

image.png

鱼, 是会游的.

image.png


青蛙, 既能跑, 又能游(两栖动物)

image.png

天鹅,既能飞,又能跑,还会游泳(三栖动物)

image.png

运行结果如下:

image.png

上面的代码展示了 Java 面向对象编程中最常见的用法: 一个类继承一个父类, 同时实现多种接口(会跑,会游,会飞).


继承表达的含义是 is - a 语义, 而接口表达的含义是 具有 xxx 特性 .


猫是一种动物, 具有会跑的特性.

青蛙也是一种动物, 既能跑, 也能游泳

天鹅也是一种动物, 既能跑, 也能游, 还能飞


【这样设计有什么好处呢?】

时刻牢记多态的好处, 让程序猿忘记类型. 有了接口之后, 类的使用者就不必关注具体类型, 而只关注某个类是否具备某种能力.


🎄接口使用实例

实例:给对象数组排序


先给定一个学生类



image.png

再给定一个学生对象数组, 对这个对象数组中的元素进行排序(按分数降序).

image.png

按照我们之前的理解, 数组我们有一个现成的 sort 方法, 能否直接使用这个方法呢?

image.png

仔细思考, 不难发现, 和普通的整数不一样, 两个整数是可以直接比较的, 大小关系明确. 而两个学生对象的大小关系怎么确定?

这时候就需要我们额外指定.

让我们的 Student 类实现 Comparable 接口, 并实现其中的 compareTo 方法

image.png

在 sort 方法中会自动调用 compareTo 方法(具体原因可以通过ctrl+左键点击sort方法查看源码,此处不多赘叙). compareTo 的参数是 Object , 其实传入的就是 Student 类型的对象.


然后自定义 比较当前对象和参数对象的大小关系 的规则(按分数来算).


如果当前对象应排在参数对象之前, 返回小于 0 的数字;

如果当前对象应排在参数对象之后, 返回大于 0 的数字;

如果当前对象和参数对象不分先后, 返回 0;

再次执行程序, 结果就符合预期了.

image.png

注意事项:

对于 sort 方法来说, 需要传入的数组的每个对象都是 “可比较” 的, 需要具备 compareTo 这样的能力. 通过重写 compareTo 方法的方式, 就可以定义比较规则.


接口就相当于是具备某种能力,在这里Comparable接口就表示具有 “可比较能力“,Student类加上(实现)了这个接口,就拥有了可比较能力,就能使用sort方法进行排序了


🎄接口之间的继承

接口可以继承一个接口, 达到复用的效果. 使用 extends 关键字

image.png

通过接口继承 创建一个新的接口 IAmphibious 表示 “两栖的”. 此时实现接口创建的 Frog 类, 就要继续通过在Frog类中 重写实现 run 方法和 swim 方法.


接口间的继承相当于把多个接口合并在一起.


🎄Cloneable 接口和深浅拷贝

Java 中内置了一些很有用的接口, Clonable 就是其中之一.


Object 类中存在一个 clone 方法, 调用这个方法可以创建一个对象的 “拷贝”.


但是要想合法调用 clone 方法, 必须要先实现 Clonable 接口, 否则就会抛出CloneNotSupportedException 异常.


给Player类实现Clonable 接口

image.png

创建一个player1对象,然后克隆一个player1

这里需要重点理解一下 深拷贝 和 浅拷贝,clone方法默认是 浅拷贝! 运行结果可以证明

image.png

运行结果如下

image.png

代码或许不太好理解,没关系,请看下图

image.png

然后将player2的 名字 年龄 都改一下

image.png

会发现一个问题,player2的age发生了修改,player1的age同时也会变,因为他们的age引用指向的是同一个地方


但是修改了名字,为什么player1的名字还是原来的kobe,而不是变成player2的奥尼尔,这是因为,字符串常量是不能被修改的,但是字符串的引用是可以修改的,所以会在字符串常量池中新创建一个字符串 “奥尼尔”,然后引用这个新的字符串


综上所述


什么是浅拷贝?


①我们这里说的浅拷贝是指我们拷贝出来的对象内部的引用类型变量和原来对象内部引用类型变量是同一引用(指向同一对象)。如上图所示

②但是我们拷贝出来的对象和新对象不是同一对象。

③简单来说,新(拷贝产生)、旧(原对象)对象不同,但是内部如果有引用类型的变量,新、旧对象引用的都是同一引用。

什么是深拷贝?


深拷贝:全部拷贝原对象的内容,包括内存的引用类型也进行拷贝

🎄总结

抽象类和接口都是 Java 中多态的常见使用方式. 都需要重点掌握. 同时又要认清两者的区别(重要!!! ).


核心区别: 抽象类中可以包含普通方法和普通字段, 这样的普通方法和字段可以被子类直接使用(不必重写), 而接口中不能包含普通方法, 子类必须重写所有的抽象方法.

image.png








相关文章
|
2月前
|
JSON Java Apache
非常实用的Http应用框架,杜绝Java Http 接口对接繁琐编程
UniHttp 是一个声明式的 HTTP 接口对接框架,帮助开发者快速对接第三方 HTTP 接口。通过 @HttpApi 注解定义接口,使用 @GetHttpInterface 和 @PostHttpInterface 等注解配置请求方法和参数。支持自定义代理逻辑、全局请求参数、错误处理和连接池配置,提高代码的内聚性和可读性。
175 3
|
2月前
|
Java 开发者
在 Java 中,一个类可以实现多个接口吗?
这是 Java 面向对象编程的一个重要特性,它提供了极大的灵活性和扩展性。
160 57
|
2月前
|
Java
在Java中实现接口的具体代码示例
可以根据具体的需求,创建更多的类来实现这个接口,以满足不同形状的计算需求。希望这个示例对你理解在 Java 中如何实现接口有所帮助。
92 38
|
15天前
|
数据采集 JSON Java
利用Java获取京东SKU接口指南
本文介绍如何使用Java通过京东API获取商品SKU信息。首先,需注册京东开放平台账号并创建应用以获取AppKey和AppSecret。接着,查阅API文档了解调用方法。明确商品ID后,构建请求参数并通过HTTP客户端发送请求。最后,解析返回的JSON数据提取SKU信息。注意遵守API调用频率限制及数据保护法规。此方法适用于电商平台及其他数据获取场景。
|
21天前
|
安全 Java API
java如何请求接口然后终止某个线程
通过本文的介绍,您应该能够理解如何在Java中请求接口并根据返回结果终止某个线程。合理使用标志位或 `interrupt`方法可以确保线程的安全终止,而处理好网络请求中的各种异常情况,可以提高程序的稳定性和可靠性。
46 6
|
1月前
|
Java
java中面向过程和面向对象区别?
java中面向过程和面向对象区别?
25 1
|
2月前
|
Java API
Java中内置的函数式接口
Java中内置的函数式接口
28 2
|
2月前
|
Java
在Java中如何实现接口?
实现接口是 Java 编程中的一个重要环节,它有助于提高代码的规范性、可扩展性和复用性。通过正确地实现接口,可以使代码更加灵活、易于维护和扩展。
171 64
|
2月前
|
Java
在Java中,接口之间可以继承吗?
接口继承是一种重要的机制,它允许一个接口从另一个或多个接口继承方法和常量。
127 1
|
2月前
|
JavaScript 前端开发 Java
还不明白面向对象? 本文带你彻底搞懂面向对象的三大特征(2024年11月Java版)
欢迎来到我的博客,我是瑞雨溪,一名热爱JavaScript和Vue的大一学生。如果你从我的文章中受益,欢迎关注我,我将持续更新更多优质内容。你的支持是我前进的动力!🎉🎉🎉
26 0
还不明白面向对象? 本文带你彻底搞懂面向对象的三大特征(2024年11月Java版)