JAVA基础——接口(全网最详细教程)_java接口怎么写-程序员宅基地

技术标签: JAVA    Java  详细  笔试笔记  接口  解耦  数据结构与算法  

                                   Java基础——接口


接口概念


    官方解释:Java接口是一系列方法的声明,是一些方法特征的集合,一个接口只有方法的特征没有方法的实现,因此这些方法可以在不同的地方被不同的类实现,而这些实现可以具有不同的行为(功能)

    我的解释:接口可以理解为一种特殊的类,里面全部是由全局常量公共的抽象方法所组成。接口是解决Java无法使用多继承的一种手段,但是接口在实际中更多的作用是制定标准的。或者我们可以直接把接口理解为100%的抽象类,既接口中的方法必须全部是抽象方法。(JDK1.8之前可以这样理解)

接口的特点


    就像一个类一样,一个接口也能够拥有方法和属性,但是在接口中声明的方法默认是抽象的。(即只有方法标识符,而没有方法体)。

  • 接口指明了一个类必须要做什么和不能做什么,相当于类的蓝图。
  • 一个接口就是描述一种能力,比如“运动员”也可以作为一个接口,并且任何实现“运动员”接口的类都必须有能力实现奔跑这个动作(或者implement move()方法),所以接口的作用就是告诉类,你要实现我这种接口代表的功能,你就必须实现某些方法,我才能承认你确实拥有该接口代表的某种能力。
  • 如果一个类实现了一个接口中要求的所有的方法,然而没有提供方法体而仅仅只有方法标识,那么这个类一定是一个抽象类。(必须记住:抽象方法只能存在于抽象类或者接口中,但抽象类中却能存在非抽象方法,即有方法体的方法。接口是百分之百的抽象类
  • 一个JAVA库中接口的例子是:Comparator 接口,这个接口代表了“能够进行比较”这种能力,任何类只要实现了这个Comparator接口的话,这个类也具备了“比较”这种能力,那么就可以用来进行排序操作了。

为什么要用接口


  1.     接口被用来描述一种抽象。
  2. 因为Java不像C++一样支持多继承,所以Java可以通过实现接口来弥补这个局限
  3. 接口也被用来实现解耦。
  4. 接口被用来实现抽象,而抽象类也被用来实现抽象,为什么一定要用接口呢?接口和抽象类之间又有什么区别呢?原因是抽象类内部可能包含非final的变量,但是在接口中存在的变量一定是final,public,static的。

接口的语法实现


    为了声明一个接口,我们使用interface这个关键字,在接口中的所有方法都必须只声明方法标识,而不要去声明具体的方法体,因为具体的方法体的实现是由继承该接口的类来去实现的,因此,接口并不用管具体的实现。接口中的属性默认为Public Static Final.一个类实现这个接口必须实现这个接口中定义的所有的抽象方法。

    一个简单的接口就像这样:拥有全局变量和抽象方法。

    为了实现这个接口,我们使用implements关键词去实现接口:

其中testClass类实现了我们上面刚才定义的 in1 这个接口,既然你要实现接口,也就是实现接口代表的一种能力,那么你就必须去实现接口给你规定的方法,只有把接口给你规定的抽象方法都给实现了,才承认你这个类实现了这个接口,实现了这个接口代表的某种功能。上图实现了接口中规定的display()方法。

    写一个测试类,用来测试一下我们刚才实现的这个接口,因为testclass类的对象t实现了接口规定的display方法,那么自然而然就可以调用display()方法咯。

    有兴趣的同学可以去这个在线IDE亲自试一试:点击打开链接

接口的进一步理解


    我们知道,如果某个设备需要向电脑中读取或者写入某些东西,这些设备一般都是采用USB方式与电脑连接的,我们发现,只要带有USB功能的设备就可以插入电脑中使用了,那么我们可以认为USB就是一种功能,这种功能能够做出很多的事情(实现很多的方法),其实USB就可以看做是一种标准,一种接口,只要实现了USB标准的设备我就认为你已经拥有了USB这种功能。(因为你实现了我USB标准中规定的方法),下面是具体的例子:

先声明USB接口:其中规定了要实现USB接口就必须实现接口规定实现的read( )和write( )这两个方法。

interface USB {
   
void read();

   
void write();
}

然后在写一个U盘类和一个键盘类,这两个类都去实现USB接口。(实现其中的方法)

class YouPan implements USB {

    @Override

    public void read() {

        System.out.println("U盘正在通过USB功能读取数据");

    }

    @Override

    public void write() {

        System.out.println("U盘正在通过USB功能写入数据");

    }

}

这是U盘的具体实现。

class JianPan implements USB {

    @Override

    public void read() {

        System.out.println("键盘正在通过USB功能读取数据");

    }

    @Override

    public void write() {

        System.out.println("键盘正在通过USB功能写入数据");

    }

}

这是键盘的具体实现。

    那么,现在U盘和键盘都实现了USB功能,也就是说U盘和键盘都能够调用USB接口中规定的方法,并且他们实现的方式都不一样。

我们在写一个测试,来看看具体的实现:

public class Main {

    public static void main(String[] args) {

        //生成一个实现可USB接口(标准)的U盘对象

        YouPan youPan = new YouPan();

        //调用U盘的read( )方法读取数据

        youPan.read();

        //调用U盘的write( )方法写入数据

        youPan.write();

        //生成一个实现可USB接口(标准)的键盘对象

        JianPan jianPan = new JianPan();

        //调用键盘的read( )方法读取数据

        jianPan.read();

        //调用键盘的write( )方法写入数据

        jianPan.write();

    }

}

结果如下:

    感兴趣的同学可以去在线IDE平台自己验证一下:点击打开链接

关于接口的几个重点


  1. 我们不能直接去实例化一个接口,因为接口中的方法都是抽象的,是没有方法体的,这样怎么可能产生具体的实例呢?但是,我们可以使用接口类型的引用指向一个实现了该接口的对象,并且可以调用这个接口中的方法。因此,上图中最后的方法调用我们还可以这样写:(实际上就是使用了Java中多态的特性)

public class Main {

    public static void main(String[] args) {

        //生成一个实现可USB接口(标准)的U盘对象

        //但是使用一个接口引用指向对象

        //USB接口类引用可以指向一个实现了USB接口的对象

        USB youPan = new YouPan();

        //调用U盘的read( )方法读取数据

        youPan.read();

        //调用U盘的write( )方法写入数据

        youPan.write();

        //生成一个实现可USB接口(标准)的键盘对象

        //但是使用一个接口引用指向对象

        //USB接口类引用可以指向一个实现了USB接口的对象

        USB jianPan = new JianPan();

        //调用键盘的read( )方法读取数据

        jianPan.read();

        //调用键盘的write( )方法写入数据

        jianPan.write();

    }

}                                                                                                                                     

 2.一个类可以实现不止一个接口。

3.一个接口可以继承于另一个接口,或者另一些接口,接口也可以继承,并且可以多继承

4.一个类如果要实现某个接口的话,那么它必须要实现这个接口中的所有方法。

5.接口中所有的方法都是抽象的和public的,所有的属性都是public,static,final的。

6.接口用来弥补类无法实现多继承的局限。

7.接口也可以用来实现解耦。

接口的通俗理解


    前面我们讲多态的时候用“空调”——“遥控器”的方式去理解多态,实际上在上面的的几个重点中的第一条讲的也是多态的实现,比如,我们可以把“节能”作为一种标准,或者说节能就是一个“接口”,这个接口中有一个方法,叫做变频方法,任何空调,如果要称得上叫做节能空调的话,那么必须实现“节能”这个接口,实现“节能”这个接口,也就必须实现“节能”接口中规定实现的“变频”方法,这样才算是真正的实现了“节能”这个接口,实现了“节能”这个功能。

    当某个空调实现了“节能”接口后,这个空调就具备了节能的功能,那么我们也可以不用空调类的引用指向空调对象,我们可以直接使用一个“节能”接口类型引用的“遥控器”去指向“空调”,虽然这个“遥控器”上面只有一个按键,只有一个“变频”的方法,但是“遥控器”所指向的空调是实现了“节能”这个接口的,是有“变频”方法的实现的,我们用这个只有一个“变频”方法的遥控器去命令空调调用“变频”方法,也是行得通的,实在不清楚的同学可以去看我的另一篇文章:JAVA之对象的多态性

接口的标识用法


    虽然接口内部定义了一些抽象方法,但是并不是所有的接口内部都必须要有方法,比如Seriallizable接口,Seriallizable接口的作用是使对象能够“序列化”,但是Seriallizable接口中却没有任何内容,也就是说,如果有一个类需要实现“序列化”的功能,则这个类必须去实现Seriallizable接口,但是却并不用实现方法(因为接口中没有方法),此时,这个Serilizable接口就仅仅是一个“标识”接口,是用来标志一个类的,标志这个类具有这个“序列化”功能。具体的实现请参考我的另一篇文章——JAVA之IO流。

接口在生活中的思想体现


其实,在我们的生活当中,有很多地方都体现了“接口”的思想,想必,正在阅读这篇博文的你,是不是也喜欢摄影呢?

佳能(Canon)EOS 80D 单反相机 单反套机(EF-S 18-200mm f/3.5-5.6 IS 单反镜头)

玩摄影的童鞋都知道,单反由相机镜头组成,相机分不同的型号,有半画幅的,也有全画幅的。镜头也是一样的,分长焦,短焦;还有定焦和变焦。每种镜头都有各自特定的发挥场景正是因为镜头的多元化,使得我们的摄影能够“术业有专攻”。大家想一想,如果我们的单反相机部分和镜头部分是固定在一起的,不能够更换镜头,那么将会多么的糟糕啊!

因此,每个相机品牌为了能够兼容不同的镜头,各自发布了一套镜头卡口的标准,这套标准就好比我们前面提到的“接口”,都是某种“约束”。举个栗子,我们佳能的相机,不管你是哪一家镜头生产厂商,腾龙也好,适马也好,只要你按照我佳能卡口的标准来生产镜头,你生产的镜头都能够很好的在我佳能相机上面驱动。

因此,当我们打开“狗东”,准备给自己的新相机买镜头的时候,就不难发现,我们需要根据自己相机的品牌来挑选特定卡口的镜头,这样的镜头才能被我们的相机正常驱动。

回到Java上面来说,其实接口给我们带来的最大的好处就是“解耦”了,相机能够搭配不同的镜头,才能有各种各样的搭配玩法,变得更加的灵活。在软件系统中也是一样的,接口可以有很多不同“特色”的实现类,我们只需要声明同一个接口,却可以引用很多个该“接口”引申出来的“子类”,这不也大大增强了我们软件系统中组件的灵活性吗?

聪明的你,对于“接口”的理解是不是又更加的深入了呢?

基础不牢?新手不友好?无人带路?关注《扬俊的小屋》公众号吧!


参考资料


1.Java开发实战经典》 李兴华著  清华大学出版社

2.https://www.geeksforgeeks.org/interfaces-in-java  作者:Mehak Kumar. and Nitsdheerendra.   翻译:刘扬俊

博客文章版权说明


第一条 本博客文章仅代表作者本人的观点,不保证文章等内容的有效性。

第二条 本博客部分内容转载于合作站点或摘录于部分书籍,但都会注明作/译者和原出处。如有不妥之处,敬请指出。

第三条 征得本博客作者同意的情况下,本博客的作品允许非盈利性引用,并请注明出处:“作者:____转载自____”字样,以尊重作者的劳动成果。版权归原作/译者所有。未经允许,严禁转载

第四条 对非法转载者,“扬俊的小屋”和作/译者保留采用法律手段追究的权利

第五条 本博客之声明以及其修改权、更新权及最终解释权均属“扬俊的小屋”。

第六条 以上声明的解释权归扬俊的小屋所有。

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/qq_19782019/article/details/80259836

智能推荐

【JZOJ5262】【GDOI2018模拟8.12】树(DP,性质题)_gdoi2018省选模拟树-程序员宅基地

文章浏览阅读460次。DescriptionSolution首先我们可以知道两个性质:1、路径u-v和路径v-w可以合并为路径u-w;2、路径u1-v1加路径u2-v2和路径u1-v2加路径u2-v1是等价的(就是起始点和终点可以互换) 那么知道这些性质之后就很好做了。我们只用知道每个点多少次做起点和多少次做终点。 我们设f[i]表示满足i子树的需求i上的值要是多少。 那么枚举i的所有儿子,判断a[i]-f[i],_gdoi2018省选模拟树

[PTA]7-65 字符串替换 (15 分)含思路_字符串替换pta-程序员宅基地

文章浏览阅读2.8k次,点赞4次,收藏28次。我们进行简单的运算即可实现倒序。_字符串替换pta

linux网络设置_linux如何开启网络连接-程序员宅基地

文章浏览阅读4k次,点赞5次,收藏22次。traceroute 180.101.50.188————————测试到180.101.50.188有多少个网关。vim /etc/sysconfig/static-routes——————————修改。netstat -antp | grep 22———————查看端口号22的相关信息。systemctl restart network————————————重启。systemctl restart network————————重新启动。_linux如何开启网络连接

pr中,视频导入后,视频画面大小显示不完整应该如何解决?_avi视频到pr里会放大-程序员宅基地

文章浏览阅读4w次,点赞23次,收藏6次。本人pr小白,今天编辑视频时候遇到了问题,也解决了,所以分享记录一下。问题一视频下面原来有字幕的,可是导入的视频变大了,现在看不到了怎么办?还有就是,频导入之后画质好像变糊了又是为什么?解决:将箭头放到要编辑的视频那里,右击,然后点击设为帧大小这样完整的视频就出来了。问题二如果视频模糊,就是序列设置的不对 要先新建序列一般的都是1920×1080本人博客:https://blog.csdn.net/weixin_46654114本人b站求关注:https://space.bi_avi视频到pr里会放大

apollo中配置map,list_apollo list-程序员宅基地

文章浏览阅读1.8k次。注:key可以不用引号,value使用单引号,但key中存在_或-等一些特殊字符时,需要加上引号,避免出错。注:key可以不用引号,value也不用引号,但key中存在_或-等一些特殊字符时,需要加上引号,避免出错。注:使用@Value注解获取,apollo中未配置时默认为null。注:使用@Value注解获取,apollo中未配置时默认为null。2.apollo中的Map配置。1.apollo中的Map配置。注:使用逗号分隔,不用引号。..._apollo list

比最快的超级计算机快一百万亿倍!中国科学家实现“量子计算优越性”里程碑_中国科学院比马普所强-程序员宅基地

文章浏览阅读4.4k次,点赞22次,收藏12次。本文来自:中国科学技术大学公众号北京时间12月4日国际顶尖杂志《Science》刊发了中国科学技术大学潘建伟、陆朝阳等组成的研究团队的一项重磅研究成果让我们一起来看看吧!中国科学家实现“量子计算优越性”里程碑中国科学技术大学潘建伟、陆朝阳等组成的研究团队与中科院上海微系统所、国家并行计算机工程技术研究中心合作,构建了76个光子100个模式的量子计算原型机“九章”,实现了具有实用前景的“高斯玻色取样”任务的快速求解。根据现有理论该量子计算系统处理高斯玻色取样的速度比目前最快的超级计算机快一百万._中国科学院比马普所强

随便推点

大数据平台核心技术 学堂在线 雨课堂 第八讲作业答案 人文交流月_vertectorization-程序员宅基地

文章浏览阅读2k次。关于Vertectorization哪些是正确的( )相对于其他编程模型,sql在大数据领域有哪些好处( )哪些部分适合做codegen( )关于内存计算描述不正确的有( )_vertectorization

java汉字拼音简码_java生成首字母拼音简码的总结-程序员宅基地

文章浏览阅读306次。百度找到了某论坛高人写的java(具体论坛记不清了),直接用来调用,再次非常感谢,基本上实现了我的需求package MD5;import java.util.Scanner;public class ChineseToPinYin {/*** 汉字转拼音缩写** @param str* 要转换的汉字字符串* @return String 拼音缩写*/public Strin..._java生成拼音码

C++ 数据结构——堆排序_数据结构堆排序c++-程序员宅基地

文章浏览阅读93次。/* 堆排序 */#include <iostream>using namespace std;int *data;void Sift(int k,int last){ int i,j,temp; i=k;j=2*i+1; while (j<=last) { if(j<last&&data[j]<data[j+1]) j++; if(data[i]>data[j]) _数据结构堆排序c++

debian 11 还不能进入命令行界面,按照网上的改也不行。_debian 无法打开命令行窗口-程序员宅基地

文章浏览阅读952次。再查查资料,有没有DEBIAN问题解答中心呢?_debian 无法打开命令行窗口

2345王牌输入法的卸载_89e1d5c2-a068-44b6-b820-f8406c8a4706-程序员宅基地

文章浏览阅读2.3k次,点赞3次,收藏10次。2345王牌输入法的卸载输入法卸载了也还有2345这个流氓输入法,研究3个小时找到了2345输入法在语言栏的根源所在,希望能帮到你windows键加R键打开运行,输入regedit 然后ctrl+F键 搜索下面路径,打开后就会看见语言栏里的输入法了,直接删除加粗这个文件夹,就删除了HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\CTF\TIP{0055AAB0-EACB-46DB-9BB4-1B97FC046D02}\LanguageProfile\0x00000804\ _89e1d5c2-a068-44b6-b820-f8406c8a4706

Android R setenforce 实现_android setenforce-程序员宅基地

文章浏览阅读2.2k次。1、开机启动system/core/init/main.cppint main(int argc, char** argv) {#if __has_feature(address_sanitizer) __asan_set_error_report_callback(AsanReportCallback);#endif if (!strcmp(basename(argv[0]), "ueventd")) { return ueventd_main(argc,._android setenforce

推荐文章

热门文章

相关标签