个人主页:Nezuko627的博客主页
❤️ 支持我: 点赞 收藏 关注
格言:立志做一个有思想的程序员
作者介绍:本人本科软件工程在读,博客将主要分享JavaSE、JavaEE、MySQL、SpringBoot、算法等知识。专栏内容长期更新,如有错误,欢迎评论区或者私信指正!感谢大家的支持~~~
本篇学习目标:
- ⭐️ 掌握接口的基本使用;
- ⭐️ 理解并熟悉接口的使用场景;
- ⭐️ 注意接口的使用细节;
- ⭐️ 掌握接口的多态特性。
基本介绍:
接口就是给出一些没有实现的方法,封装到一起,到某个类需要使用的时候,再根据具体情况实现方法。 其基本语法如下:
// 定义接口
interface 接口名{
属性;
方法;
}
// 具体类实现接口
class 类名 implements 接口名{
属性;
方法;
实现所有接口中的抽象方法;
}
️ 注意! 在 jdk7.0
以前,接口里的所有方法都没有方法体,都是抽象方法;在 jdk8.0
后,接口可以有静态方法,默认方法,即可以有方法的具体实现。
示例:
深入讨论:
对于萌新来说,接口的概念和基本使用其实并不难,难点就在于我们并不知道什么时候该用接口,下面我们来举几个实际例子:
⭐️ 需要制造一批汽车。专家只需要把汽车需要的功能(导航、刹车、座椅调节等)以及规格(各种零件大小等)定下来即可,剩下的让工人具体实现就行。
⭐️ 有一个项目经理,管理3个程序员开发一个软件。为了控制和管理软件,项目经理定义一些接口,然后由程序员具体实现。(虽然程序员可以直接写相应的类,但是难免会不合规范,比如需要写三个类,每个类都需要实现连接一种数据库的方法,程序员 A 取名为 f1(),程序员 B 取名为 con(),程序员 C 取名为 connect() ,这就产生了,连接数据库这一操作竟然有三个不同名称的方法,到底该用哪个呢?无形中增加了思考维护的成本)
总的来说,我们可以这样理解接口: 接口其实是一种开发规范,便于我们在实际开发中管理和维护代码。 当然,接口的妙用还不仅如此!后面的接口多态特性,小伙伴们会有更深的体会!
1️⃣ 接口不能被实例化;
2️⃣ 接口中的所有方法都是 public
方法, 接口中的抽象方法,可以不用 abstract
修饰;
解释:
我们很容易证明接口中的方法是默认有
abstract
修饰的,因为抽象方法没有方法体。但是如何证明接口中的方法都是public
的呢?
这里,我们需要回顾一个知识点,即:子类不能缩小父类的访问权限
也就是说,我们只需要子类去实现接口中的抽象方法,定义子类实现的具体方法的访问权限为default
即可,结果如下图:
我们发现,编译器报告了错误!也就是说,default
是比接口还要严格的修饰!因此,接口中的方法都是public
!!!
3️⃣ 一个普通类实现接口,必须将该接口的所有方法都实现,在 idea 编译器中,可以使用 alt
+ enter
快捷键来快速实现,图示如下:
4️⃣ 抽象类可以不实现接口中的所有方法。 没什么好说的,因为是抽象类鸭;
5️⃣ 一个类同时可以实现多个接口;
示例代码:
class 类名 implements 接口1, 接口2......{
// 实现接口部分
}
6️⃣ 接口中的属性只能是 final
的,而且必须用 public static final
修饰,而且必须初始化;
例子:
int a = 1 实际等价于 public static final int a = 1;
7️⃣ 接口不能继承其它类,但是可以继承多个别的接口;
示例代码:
interface 接口名 extends 接口1, 接口2......{
// 定义部分
}
8️⃣ 接口的修饰符只能是 public
与 default
。
❓ Question: 阅读代码块,编译是否会通过?如果能通过,输出是什么?
interface A{
int a = 18;
}
class B implements A{
}
public class Main {
public static void main(String[] args) {
B b = new B();
System.out.println(b.a);
System.out.println(A.a);
System.out.println(B.a);
}
}
考点: 接口中的属性只能是 final
的,而且必须用 public static final
修饰,而且必须初始化。
参考答案:
18
18
18
在这里我们举个例子:手机、平板与电脑。其中手机、平板分别通过数据线与电脑连接。手机、平板作为USB接口的实现类,实现了开机的方法,图示如下:
设计参考示例代码如下:
⭐️ Usb接口
// Usb接口
interface Usb{
void start(); // 开机抽象方法
}
⭐️ Iphone类
// Iphone类
class Iphone implements Usb{
@Override
public void start() {
System.out.println("iphone 开机......");
}
}
⭐️ Ipad类
// Ipad类
class Ipad implements Usb{
@Override
public void start() {
System.out.println("ipad 开机......");
}
}
⭐️ 测试类
public class InterfaceTest {
public static void main(String[] args) {
// 创建一个手机,创建一个平板
Iphone iphone = new Iphone();
Ipad ipad = new Ipad();
// 创建一个电脑
Computer computer = new Computer();
// 使用设备
// iphone ipad 均为接口实现类,存在向上转型,是多态参数的体现
// 不同对象调用不同的方法
computer.use(iphone);
computer.use(ipad);
}
}
实现结果:
iphone 开机…
ipad 开机…
在该例子中,测试方法调用了 Computer类的 use()
方法,根据传入的对象类型不同(iphone 与 ipad)作用的结果不同。 即既可以接收手机对象,又可以接收平板对象,体现了接口的参数多态。
在这里,博主偷个懒。我们继续使用上面的手机、平板、电脑的例子。只不过有一些区别:
给 Usb 数组中,存放 Iphone 和 Ipad 对象,Iphone 类中还有一个特有方法 call 用于打电话,遍历 Usb 数组,如果是 Iphone 对象,除了调用 start 方法外,还要调用 call 方法打个电话。
Iphone类修改:
// Iphone类
class Iphone implements Usb{
@Override
public void start() {
System.out.println("iphone 开机......");
}
// 打电话
public void call(){
System.out.println("iphone 打电话中......");
}
}
测试类修改:
public class InterfaceTest {
public static void main(String[] args) {
// 创建 Usb 数组
Usb[] usb = new Usb[2];
usb[0] = new Ipad();
usb[1] = new Iphone();
// 判断类型,相应操作
for (int i = 0; i < usb.length; i++) {
usb[i].start();
// 如果是手机
if (usb[i] instanceof Iphone){
((Iphone) usb[i]).call();
}
}
}
}
实现结果:
ipad 开机…
iphone 开机…
iphone 打电话中…
这里使用到了向下转型,其中 usb 就是多态数组。 向下转型相关请传送:
❤️ 【JavaSE】面向对象之多态、向上转型与向下转型
在本文中,我们已经学习到, 接口类型的变量可以指向实现了该接口的类的实例对象。 而特别地,当接口类型的变量指向实现了继承该接口的类的实例对象,我们就称之为接口的多态传递现象。 即接口类型的变量,也可以指向实现了该接口的子接口
的实例对象(当然没有子接口这一说法哦~)。
示例代码如下:
解释: Iphone 继承了 Usb接口, 而 Ipad 类实现了 Iphone 接口实际上就相当于 Ipad类 实现了 Usb接口
以上便是本文的全部内容啦,后续内容将会持续免费更新,如果文章对你有所帮助,麻烦动动小手点个赞 + 关注,非常感谢 ❤️ ❤️ ❤️ !
如果有问题,欢迎私信或者评论区!
共勉:“你间歇性的努力和蒙混过日子,都是对之前努力的清零。”