我们在上一章说到实现java多继承的方法,并且介绍了关于内部类的相关知识点。接下来我们介绍的是另一种办法:接口。我们知道 ,继承的目的是为了多态,而接口,则是实现多态的另一种重要途径。灵活掌握接口的用法及精神,将有助于我们写出更易于阅读和维护的代码。而这一点对于每个程序员而言都是梦寐以求的事情所以,如果我们要成为一名优秀的面向对象编程的程序员,又怎么能忽略这个重要的知识点呢?接下来,我们就开启学习接口的大门吧。
一、什么叫接口
从理解上而言,接口应该是一种连通器。它实现将用户需要的一些东西传送到用户想要存放的地方,并且在执行上是相对简单的。比如:电脑上的USB接口,可以让我们的电脑文件和手机、内存卡连起来而不是手打一遍。水龙头接口可以让我们把自来水和容器连接起来而不用跑到十八里外的河边去挑水回来、可以说,世界上有很多接口存在,我们周围用到的一切东西,都有可能是一个实际的接口。那么,在面向对象编程中,什么样的东西才叫做接口呢?实际上,如果你足够细心,你会发现,我们在讲类与对象这一章的时候,讲的就是类是从客观事务中抽象出来的一个名词。同样的,在面向对象编程理念中,接口也是从客观事务中抽象出来的一组数据模型。从形式上而言,如果说类是一种模板,那么接口就可以理解为一种协议。就比如说,现在用三家银行,都打算做一个自动取款机的应用。但从设计上而言,三家银行的操作方法,取款上限,手续费利率等等都未必会一样。但是这些功能都是必须实现的。怎么办呢?那我们就可以为其做一个协议。协议规定了一个自动取款机应该具有什么功能,但是具体的实现方式,就交给银行自己去定义。但是不管银行怎么定义,都不能违反协议的规定。而这个协议,就是一个接口,三家银行代表的就是三个需要实现该接口的对象类。在对象类中需要实现接口所提供的一切方法,但具体的实现方式则根据需求来定义。也就是说:接口就是一种结构设计工具,用来解耦合,可以理解为定义一种共同的协议,具体实现由最终所继承的子类实现。而在这里,接口是可以实现多个的,就好像一个人可以加入很多的兴趣组织,那么就需要遵守你所加入的组织规定的协议就好了。而这样的方式,正好弥补了java单继承机制带来的缺点。一举多得。
二、接口的用法
我们在上面用了类的定义来帮助解释接口,就说明接口其实并不是类,尽管编写接口的方式和类很相似,但是它们属于不同的概念。类描述对象的属性和方法。接口则包含类要实现的方法。准确来说,接口在语法上表现与类相似,但却完全不同。其语法如下:
[权限控制符] interface 接口名称 [extends 其他的类名]|[implements 其他的接口] {
// 声明变量
//抽象方法
}
注意的是,在这里,之所以用抽象方法一词。是因为我们是在定义一个各方需要遵守的协议,而不是给出具体的方法,也就是说,我们仅需定义一个框架,内容有子类来完善。所以,在接口中是不能够有具体的方法的。
譬如:
//错误示例:
public interface ErrorSample{
void sleep(){
System.out.println("四脚朝天地睡觉");
}
}
//正确示例
public interface TrueSample{
public void sleep();
}
而基于这一原因,我们得出了接口的一个特点:接口是不能直接new出一个实例的,它只能通过一个子类去继承并实现其定义的抽象办法。也就是说,我们不能直接用
ErrorSample error = new ErrorSample();
这样的方式去实现接口,而应该是这样:
public class SubClass implements TrueSamole{
void sleep(){
System.out.println("四脚朝天地睡觉");
}
}
在这里,我们发现,从语法上而言,我们用class定义类,而用interface定义接口。用extends表示继承父类,而用implements表示继承一个接口。由此我们可以得出:类和接口尽管相似,但两个同样有着不少的区别。下面我们来探讨一下两者的似与不似:
相似点:
都是实现多态性的重要载体(通过继承使子类具有父类的某种特性
不同点
除了 static 和 final 定义的变量之外,接口不能包含其他的成员变量。
三、接口的作用
我们前面讲了接口的一些基础知识,但是我们为什么要用接口呢?这就关系到接口的作用了,按照个人的理解,接口的作用有如下三点:
1.明确编码规范
什么意思呢?前面我们说接口就是一种协议,其本质就是一种规范性的行为。它可以有效避免了其他开发者在编码的过程中可能出现的因为忽略了对某种情况的思考而使得程序出现bug。而事先使用接口明确编码规范,再交由其他开发者去实现的话,可以有效避免bug的发生。这一点体现在公司上而是由经验丰富的架构师编写接口文档,程序员依据文档进行具体的实现,也就是我们所提倡的:接口与实现分离。
2.提高代码的可拓展性:
我们知道,产品是只磨人的小妖精,随时随地都有可能更改需求。那么,如果我们实现一个功能,就要在原有代码的基础上进行更改的话,不仅容易使得代码的可读性降低,还容易引发因修改代码而产生的bug,使得程序的性能及维护效率也变得很差。不符合程序设计中的开闭原则。而使用接口,对各功能进行进行抽象之后,当我们增加某一更能时,只需新增一个功能类并通过实现接口的方式来进行。从而避免了在原有代码上进行修改的可能。
3.实现多态:
我们知道,多态的存在使得面向对象编程变得更加地灵活与方便。能够使程序具有可复用性,同时因为子类的功能能够被父类变量或者引用对象引用。从而提高可扩充性和可维护性。而接口的存在,则成了实现多态的一把利器。我们甚至可以通过子类继承接口的方式,使得该类变成一个接口类型。
如果说要当一名优秀的程序员,或者当一名架构师的时候,需要对多态有一个非常深入的理解,而要深入理解多态,必不可少的,也要清楚接口的含义及架构。或许说:一个接口,多种实现这句话就已经非常明确地表明了接口的重要性了吧。
至此,关于接口的基础知识已经介绍完毕,那么如何去学习、理解接口,或者说如何去了解多态呢?我想,除了要多上手练项目之余,还应该在写项目之前,多尝试对程序的功能进行分析,将一些功能的特质抽象一下,尝试去形成一个接口。而不是拿到项目就立即上手敲。更多的是基于程序的理解而进行分析吧。如果能画出相应的UML的话,那应该也是极好的事情了。
曾经听到有人说,一个敲码只需要8分钟的模块,用来分析的时间需要2个小时。我想,这就很清楚地说明了分析程序的重要性,所以,在敲代码之前,还是要更多的分析,才有更多的理解。同时,也能减少出bug的几率。磨刀不误砍柴工,不然一辈当码农~
好了,我们下一章的内容是“java-面向对象编程-抽象类”。敬请期待。如对文章有疑问,可在文章下方留言阐述。