文章目录
1.接口快速入门
我们的这个快速入门还是使用的这个日常生活里面的这个USB接口,我们下面的这个案例会定义一个接口,然后让这个手机和相机重写这个接口里面的方法,然后让这个computer实现这个接口的参数的接受;
我们的这个接口里面是有一个开始工作和停止工作的抽象的方法,这个时候我们的camera和phone都要实现这个接口,因此需要对于这个接口里面的方法进行重写,这个implements就是实现的意思,表示我们的这个类要对于这个接口进行重写;
我们的这个computer需要接受,因为我们的这个日常生活里面,computer相当于是自己的接口上面插上来了这个手机和相机,因此我们的这个computer里面是有一个方法的参数就是接口,这个可以是我们的这个camera,也可以是我们的phone,传过来什么我们的这个就接受什么,如果传递过来的是相加,那么这个就会打印相机开始工作,相继结束工作;
2.接口基本介绍
下面的这个也是一个接口,我们需要对于这个接口里面的方法进行解释:
接口里面的这个方法默认是抽象的方法,在jdk7之前,这个方法是不允许有方法体的,但是在这个jdk8之后,这个方法不仅可以有方法体,而且可以有静态的方法和默认实现的方法;
下面的这个例子里面,我们的这个hi方法就是抽象的方法,实现这个接口的类都需要对于这个抽象的方法进行重写,这个方法虽然没有加上这个abstract但是这个默认就是抽象的方法;
下面的这个ok方法是默认实现的方法,为什么叫做默认实现的方法呢,就是因为这个default就是默认的意思,我们的这个方法正常写就会报错,但是我们加上这个default进行修饰之后,这个方法就成为了默认实现方法,就可以出现在我们的这个接口里面了;
我们的这个test02方法是一个静态的方法,这个方法也是可以在我们的接口里面的,这个静态方法和默认实现的方法都是在jdk8之后允许的,但是我们的这个目前的jdk已经更新到20+了,因此我们是可以正常使用的;
package Interface;
public interface AInterface {
//我们可以写属性,方法
public int number1 = 10;
//接口里面默认就是抽象的方法
public void hi();
//jdk8.0之后,我们的接口里面可以有实现的默认方法和静态方法
default public void ok(){
System.out.println("ok........");
}
// 接口里面可以有静态的方法,可以实现
public static void test02(){
System.out.println("test02()");
}
}
3.接口应用场景
相信上面对于接口的介绍,我们对于这个接口里面的这个相关的方法的使用条件,以及一些默认的属性有了一定程度的了解,但是学以致用,我们学习的目的就是为了使用,同样我们学习接口的目的也是为了使用,下面我们通过一个简答的例子对于这个接口的使用做一个说明;
具体需求
我们的一个项目经理管理三个程序员,让三个程序员分别实现对于三种不同的数据库的连接,这个时候,正常情况下,就会三个程序员各自实现各自的功能,我们的数据库有链接和关闭的功能的实现,对于这个方法吗,可能我们三个程序员会有不同的定义,这个时候我们在对于这个项目进行实现的时候,需要调用这个方法就显得很麻烦;
例如下面的这个图片里面展示的这个mysql oracle和seq server三个数据库,三个程序员分别负责三个数据库的连接和关闭,这个时候,如果让我们的程序员自己搞,这个时候的名字可能就会五花八门,不便于我们后期的测试和维护;
但是如果我们的这个项目经理对于这个链接和关闭以接口的形式进行管理,这个时候我们的三个程序员都需要实现这个接口,自己的这个连接方法里面都需要对于这个接口进行实现的方法的重写,这个时候名字就是一样的,因为进行方法的重写的要求就是我们的这个方法名字必须要一样,否则就报错
这样,我们进行测试的时候,只需要像上面的一样,定义一个类似于这个computer这样的类,这个里面的方法接收这个对象,当我们的这个mysql传过来的时候,我们就测mysql的关闭和连接功能,当这个sql server传递过来的时候,我们就去测试这个sql server的相关的功能,这个时候,这个事情方便我们管理,而且这个方法都是一样的;
通过上面的这个案例,相信你也对于这个接口有了更进一步的了解,当然这个接口的威力远不止于此,我们的这个接口就相当于一套规范,我们的实现必须对于这个接口里面的方法重写,对于这个接口进行实现,因此这个就极大的提高了我们的代码的可读性,避免了不同的模块之间的这个混战(就是对于相同的功能,这个方法的名字起的五花八门),相比之下,这个接口更方便我们对于这个项目的管理和维护;
4.接口的使用细节
//1.接口不可以进行实例化(new就会出错)
//2.默认方法都是public,抽象方法可以不用abstract修饰(没有方法体)
//3.一个普通的类继承接口,需要实现这个接口里面的所有的方法—类实现接口
//4.抽象类实现接口的时候,可以不用实现这个接口的方法----类一般都要实现这个接口的方法,但是如果这个类是抽象类,就不需要实现接口;
//5.一个类可以同时实现多个接口:implements A,B这样表示即可,就是这个implements这个关键字的后面加上我们的这个多个接口也是可以的;
//6.接口里面的属性,都是public static(通过接口。访问) final修饰的
//7.接口不可以继承其他的类,但是可以继承其他的多个接口:强调接口之间的继承性,但是接口和类之间没有继承关系;
//8.接口的修饰符只可以是public和默认:和我们的普通的属性是一样的;
5.接口VS继承
接口仿佛实现了多重继承的功能:子类继承父类的功能,如果想要拓展这个功能,我们就可以使用接口的方式,接口是对于java单继承的补充;
下面的这个里面的money就是我们的父类,我们的littlemoney就是继承父类的一个子类,这个时候我们的这个子类里面的,其实就是默认有了这个父类的方法,像这个猴子会爬树,我们在这个父类里面实现了这个爬树的方法,这个时候子类就是默认有的,
但是如果我们想让这个猴子有这个有游泳和飞翔的功能,这个时候我们是无法进行操作的,因为每一个只可以是继承一个类,就是在我们的Java体系里面,不支持多继承,这个时候我们可以使用我们的接口实现这个功能;
然后我们就可以在这个main方法里面创建对象进行这个方法的调用,这个时候相当于我们的这个子类通过继承有了这个climbing的方法,通过这个接口的方式拥有了这个flying和swiming的特性,这个就间接地实现了我们的多继承(本质上不支持多继承,但是接口可以帮助我们实现这个功能的扩大,这个仅仅依靠继承是无法实现的,因为我们的这个继承只可以是单继承)
6.接口的多态特性
6.1多态的体现
首先就是我们的这个接口虽然不可以实例化对象,但是我们的实现接口的子类new的对象可以传递给我们的接口,而且传递什么类里面的对象,我们的接口就可以调用相应的方法-------------接口的引用可以指向接口的类创建的对象;
6.2多态的参数
就是我们上面写过的这个入门的案例,我们的这个电脑里面的参数就体现了多态的特性,我们的这个传递的参数可以是这个camera对象,也可以是这个phone对象,根据这个对象的不同,我们会调用不同的类里面对应的方法;
6.3多态数组
下面的这个代码案例里面,我们定义类一个接口,然后这个相机和手机需要去实现这个接口,其中这个手机里面还有一个call方法是自己独有的;
这个时候,我们使用这个接口创建了一个多态数组,为什么叫做多态数组;就是因为这个数组的两个元素分别属于不同的类,我们使用这个接口里面的这个work方法的时候,如果我们的这个参数是这个phone类里面的,这个时候调用的就是phone重写的方法,否则就是我们的camera重写的方法;
我们的这个call方法是这个phone独有的,我们想要进行调用,首先需要对于这个数组里面的元素进行判断,如果这个引用指向的就是我们的手机类,这个时候就需要使用向下转型的方法转换之后调用这个call方法;
6.4接口多态传递
上面的这个代码里面,我们的teacher这个类继承自我们的IG接口,因此我们的这个IG接口类型的变量可以去接受这个teacher的实例化对象,但是我们的这个IH是这个IG的父类,这个就是相当于我们的这个IH接口的变量也可以接受这个teacher的实例化对象-这个就是接口的多态传递;
6.5接口继承的冲突
下面的这个代码里面,我们的接口和父类里面各自定义了一个x,当我们的这个func函数调用的时候,会打印这个x的数值,当我们不进行任何指定的时候,这个就会产生歧义,正确的做法就是我们的这个想要打印父类的x使用super关键字,想要打印这个接口里面的x使用这个类.x,因为我们的这个接口里面的变量属于是静态的,可以直接使用类点出来;