接口与抽象类,区别以及使用场景 标签: java接口抽象类接口与抽象类

文摘:


接口+实现”最常见的优势就是实现类和接口分离,在更换实现类的时候,不用更换接口功能:既一个方法的形参数是一个接口对象

那么凡是实现了这个接口的类都可以作为实参传入,并且,接口对象调用的只能是子类所实现的接口的方法,这样就降低了模块之间的

耦合性


  很多JAVA初级程序员对于接口存在的意义很疑惑。不知道接口到底是有什么作用,为什么要定义接口。

      好像定义接口是提前做了个多余的工作。下面我给大家总结了4点关于JAVA中接口存在的意义:

  1、重要性:在Java语言中, abstract class 和interface 是支持抽象类定义的两种机制。正是由于这两种机制的存在,才赋予了Java强大的 面向对象能力。

  2、简单、规范性:如果一个项目比较庞大,那么就需要一个能理清所有业务的架构师来定义一些主要的接口,这些接口不仅告诉开发人员你需要实现那些业务,而且也将命名规范限制住了(防止一些开发人员随便命名导致别的程序员无法看明白)。

  3、维护、拓展性:比如你要做一个画板程序,其中里面有一个面板类,主要负责绘画功能,然后你就这样定义了这个类。

         可是在不久将来,你突然发现这个类满足不了你了,然后你又要重新设计这个类,更糟糕是你可能要放弃这个类,那么其他地方可能有引用他,这样修改起来很麻烦。

         如果你一开始定义一个接口,把绘制功能放在接口里,然后定义类时实现这个接口,然后你只要用这个接口去引用实现它的类就行了,以后要换的话只不过是引用另一个类而已,这样就达到维护、拓展的方便性。

  4、安全、严密性:接口是实现软件松耦合的重要手段,它描叙了系统对外的所有服务,而不涉及任何具体的实现细节。这样就比较安全、严密一些(一般软件服务商考虑的比较多)。


接口是个规范”,这句没错。
不如直接就在这个类中写实现方法岂不是更便捷”,你怎么保证这个接口就一个类去实现呢?如果多个类去实现同一个接口,程序怎么知道他们是有关联的呢?

既然不是一个类去实现,那就是有很多地方有用到,大家需要统一标准。甚至有的编程语言(Object-C)已经不把接口叫 interface,直接叫 protocol。

统一标准的目的,是大家都知道这个是做什么的,但是具体不用知道具体怎么做
比如说:
我知道 Comparable 这个接口是用来比较两个对象的,那么如何去比较呢?
数字有数字的比较方法,字符串有字符串的比较方法,学生(自己定义的类)也有自己的比较方法。


你写接口你写实现,就不用写接口了。
我写接口你实现,接口不就用上了。我不给你规定好了,你怎么知道该实现哪些内容呢。
更进一步,我写接口你实现,你今天不在,我明天出差,程序后天交工,那我今天必须把调用这个接口的代码写好。所以就需要接口中有函数,有明确的函数签名。我写个接口,再把调用函数写好,明天你把接口实现了,传个实例进来,交工。




接口和抽象类应该是Java语法中最常见的两个概念

关于两者,网上也是一搜一吨的对比,总体如下:

1,抽象类的成员可以具有访问级别 接口的成员全部public级别
2,抽象类可以包含字段 接口不可以
3,抽象类可以继承接口 接口不能继承抽象类
4,抽象类的成员可以具有具体实现 接口不行
5,抽象的子类可以选择性实现其基类的抽象方法 接口的子类必须实现

6,接口是抽象类的一种特例!

概念虽然简单

不过到具体使用场景中,什么情况下用抽象类,什么情况下用接口呢,很多人却搞不明白


下面我举个例子

有一个Door,里面有方法open()和方法close()

我们要把他抽象出来,形成一个类,可以有下面两种方法

1,抽象成抽象类,如下

[java]  view plain  copy
 print ?
  1. abstract class Door{  
  2.     void open() {}  
  3.     void close(){}  
  4. }  


2,抽象成接口,如下

[java]  view plain  copy
 print ?
  1. interface Door{  
  2.     void open();  
  3.     void close();  
  4. }  

看起来两者好像没啥区别,现在我们要加一个功能,门铃功能

没啥问题,那就加上

1,抽象类

[java]  view plain  copy
 print ?
  1. abstract class Door{  
  2.     void open() {}  
  3.     void close(){}  
  4.     void bilibili(){}  
  5. }  

2,接口

[java]  view plain  copy
 print ?
  1. interface Door{  
  2.     void open();  
  3.     void close();  
  4.     void bilibili();  
  5. }  


那么问题来了,所有门都有开关门功能,是不是所有的门都有门铃呢?

那不是所有的实现Door的类都得具有门铃方法?


所以,我们应该把门铃理解成一种附件,一种Attach,可以加到门上面的一种点缀

对于这种附件形式的类,我们就可以用接口来表示


所以,啥叫接口,就是在门上凿出一个门铃大小的洞,用来放门铃的,就跟电脑上的usb接口一样,一个洞嘛!


我们就可以这样来定义铃声这样一个接口

[java]  view plain  copy
 print ?
  1. interface Ring{  
  2.     void bilibili();  
  3. }  
这样定义Door这个类

[java]  view plain  copy
 print ?
  1. abstract class Door{  
  2.     void open() {}  
  3.     void close(){}  
  4. }  

这样,如果有一个铃铛的门,可以这样来写:

[java]  view plain  copy
 print ?
  1. class DoorWithRing extends Door implements Ring{  
  2.   
  3.     public void bilibili() {  
  4.         // TODO Auto-generated method stub  
  5.           
  6.     }  
  7. }  

如果是一个没有铃铛的门

[java]  view plain  copy
 print ?
  1. class DoorWithRing extends Door{  
  2.   
  3. }  


现在我们要在门上装一个猫眼,咋装呢,很简单

买个猫眼:

[java]  view plain  copy
 print ?
  1. interface CatEye{  
  2.     void see();  
  3. }  


把猫眼装进门上的洞里:

[java]  view plain  copy
 print ?
  1. class DoorWithRingAndCatEye extends Door implements Ring,CatEye{  
  2.         public void see() {  
  3.             // TODO Auto-generated method stub  
  4.               
  5.         }  
  6.         public void bilibili() {  
  7.             // TODO Auto-generated method stub  
  8.               
  9.         }  
  10.     }  

一个门上可以打无数的洞,也就是可以实现多个接口!


有人会问,门铃,猫眼,这些东西不也是类吗,为啥不做成类,做成接口呢?


对的,当然可以做成一个正常的类,有他的属性什么的,这样猫眼,门铃和门的关系就变了,变成聚合关系了,不是组合,因为门没了门铃和猫眼还是门,这些基本的概念有机会再延伸吧


所以,对于那种功能单一(响铃,看人),又需要拿来作为一个附件附加到基本类上的类,我们就把它定义成接口



ok!

你可能感兴趣的:(java)