java中抽象类和接口之间的区别和关系

来源:blog.csdn.net 更新时间:2023-05-25 21:55

首先抽象类归根结底还是属于类,对于抽象方法,是只能存在于抽象类中的,我们无法再一个非抽象的类中声明一个抽象方法,其次抽象方法只需要声明,并不需要事先。当我们要写一个抽象类的时候只需要在类的前面声明为abstract即可了。同时抽象类是无法被实例化的,而抽象类的存在就是为了被继承的,在我们定义类的时候,有的时候需要定义一个这样的抽象类但是不想将其进行实例化的时候就可以定义一个抽象类,比如我们想要定义一些动物的类,这些动物包含很多不同种的动物,但是我们也的确没有必要实例化一个总的动物的对象,因为并不存在这样的对象。我们值得注意的是,对于抽象类,有以下三点值得我们注意:

  1、抽象类中的抽象方法必须定义为protected或者public,因为如果我们将其定义为私有的话,就无法被子类继承(其实也不是不好继承,而是不好调用)

  2、抽象类中的抽象方法如果没有在某一个子类中实现(也就是该子类直接继承了这个父类而没有重写该抽象方法),该子类也必须定义为抽象类

  3、抽象类是不可以实例化的。

  在其他方面,抽象类并没有表现出和普通的类的不同。

 

[java] view plain copy
  1. [public] abstract class MyClass{  
  2.     abstract int fun();  
  3. }  

  我们可以看的到,抽象类的诞生就是为了继承的。

 

  然后我们再来看接口(interface),首先接口是一种完完全全抽象的类(当然也有人说接口并不是类,不过这不重要),接口是为方法而生的,是作为一种方法的抽象存在的,接口中可以有变量和方法,但是接口中的变量是被强制置为public static final 的,并且只能为该类型,一旦用private来修饰就会报出错误。对于接口中的方法,能且只能是public abstract方法,而且对于接口中的方法都不能有具体实现(实际上抽象方法都是这样的)。在这里我们也可以看得出来接口和类之间的巨大区别,接口看上去更加纯粹的抽象。接口以关键词interface来修饰。

 

[java] view plain copy
  1. [public] interface InterfaceName {  
  2.    
  3. }//这是一个空的接口  

  接口解决了一个非常重要的问题,就是多重继承的问题,我们定义了一个类,它肯定是不可以继承自多个类的(这个很容易理解,因为如果这两个类有相同名字和参数表返回值的方法,对于同时继承了这两个类的子类在调用相应方法的时候,最终调用哪一个就成了一个让人头疼的问题),但是接口不一样,我们定义的任何一个类是可以实现多个接口的,同时对于一个接口在不同的类中也可以有不同的实现.

 

  下面我们简单分析一下接口和抽象类在各个方面不同的区别:

  在语法方面:

  1、在抽象类中的方法是可以有具体的实现的,只是对于这个类而言不存在实例化这个过程,而在接口中的方法只能是public abstract的;

  2、在抽象类中的变量是可以有多种的,但是在接口中只能是public abstract final的

  3、接口中是不能含有静态代码块或者静态方法,但是抽象类中是可以有静态代码块和静态方法

  4、一个类只能继承一个抽象类,但是一个类可以实现多个接口

  同时,在定义和设计的方面:

  抽象类归根结底还是更像类一些,也就是说实际上还是对现实事物的描述,而接口则是一种对行为的抽象。

  下面是一个在网上广泛流传的例子,门和警报的例子:门都有open( )和close( )两个动作,此时我们可以定义通过抽象类和接口来定义这个抽象概念:

 

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

或者

 

 

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

 

但是现在如果我们需要门具有报警alarm( )的功能,那么该如何实现?下面提供两种思路:

  1)将这三个功能都放在抽象类里面,但是这样一来所有继承于这个抽象类的子类都具备了报警功能,但是有的门并不一定具备报警功能;

  2)将这三个功能都放在接口里面,需要用到报警功能的类就需要实现这个接口中的open( )和close( ),也许这个类根本就不具备open( )和close( )这两个功能,比如火灾报警器。

  从这里可以看出, Door的open() 、close()和alarm()根本就属于两个不同范畴内的行为,open()和close()属于门本身固有的行为特性,而alarm()属于延伸的附加行为。因此最好的解决办法是单独将报警设计为一个接口,包含alarm()行为,Door设计为单独的一个抽象类,包含open和close两种行为。再设计一个报警门继承Door类和实现Alarm接口。

 

[java] view plain copy
  1. interface Alram {  
  2.     void alarm();  
  3. }  
  4.    
  5. abstract class Door {  
  6.     void open();  
  7.     void close();  
  8. }  
  9.    
  10. class AlarmDoor extends Door implements Alarm {  
  11.     void oepn() {  
  12.       //....  
  13.     }  
  14.     void close() {  
  15.       //....  
  16.     }  
  17.     void alarm() {  
  18.       //....  
  19.     }  
  20. }