java 抽象类和接口

这段时间学习Java类库源码,发现自己对于Java的一些基本特性掌握的不是很好,例如接口与抽象类的一些特性,所以重新翻看《Core Java》,将两者的相关内容整理一下。

转载请注明出处。

————————————————————————————————————————————

————————————————————————————————————————————


Java中的接口和抽象类都是抽象机制的实现,两者有许多共同点,也有一些不同点,要注意区分。


抽象类

在继承结构中,上层的类比下层的类更具有通用性,更加抽象。有些时候,我们只想把上层类作为派生其他类的基类,而不作为特定的实例类,这时候抽象类就派上用场了。如果类中的一个方法用abstract 关键字修饰,则不需要实现这个方法,而是把实现留给继承它的类。例如:
[java]   view plain copy
  1. public abstract class AbstractPerson {  
  2.     public abstract String getDescription();  
  3. }  

必须注意,出了抽象方法之外,抽象类还可以包含其他具体数据和具体方法(提供实现)。如下:
[java]   view plain copy
  1. package cd.edu.hfut.comparable;  
  2.   
  3. /** 
  4.  * @author bingduanLin 
  5.  * 
  6.  */  
  7. public abstract class AbstractPerson {  
  8.     public abstract String getDescription();  
  9.       
  10.     /** 
  11.      * @return  
  12.      */  
  13.     public String getName() {  
  14.         return this.name;  
  15.     }  
  16.       
  17.     private String name;  
  18. }  
如果一个类含有抽象方法,则类本身也必须声明为抽象的。抽象类不能被实例化,但是可以声明一个抽象类的对象变量,这个对象变量只能引用抽象子类的对象。例如,Employee类继承自Person,则可以如下声明:
[java]   view plain copy
  1. Person person = new Employee()  


在子类中,可以实现部分或者全部抽象方法。如果实现部分抽象方法,则子类仍然是抽象类。如果所有方法都被实现,则子类不再是抽象类。另外,即使不含抽象方法,也可以将某个类声明为抽象类。

现在如果有一个类继承了Person,如下:
[java]   view plain copy
  1. class Employee extends AbstractPerson {  
  2.   
  3.     @Override  
  4.     public String getDescription() {  
  5.         return this.des;  
  6.     }  
  7.       
  8.     String des;  
  9.       
  10. }  

现在,上面的person对象变量可以调用p.getDescription方法了,而且结果也将返回des。这里需要解释一下,由于抽象类不能被实例化,所以person引用的永远不可能是Person对象,也就是说,只能引用具体的子类,而这些子类中都实现了getDescription方法,当然就可以调用啦。
在java集合框架中,有许多抽象类,例如 AbstractCollection, AbstractSet, AbstractList等等。可以查看源码了解更多。

接口

Java中的接口,是对类的一组需求描述,遵循接口的统一格式。

在接口中,只能提供方法的声明,而不能实现方法的具体细节。所有方法自动声明为public,所以可以不提供关键字public,但是标准库中有些接口还是加上public,例如Comparable接口中的compareTo方法。在实现接口时,必须声明为public。

出了方法声明之外,接口中还可以定义常量。常量自动被声明为public static final,所以可以省略这一些,一样的,可以加上去使代码更加清晰。标准库中的SwingConstant接口中只包含诸如North之类的常量而没有方法声明,于是实现这一接口的类就可以直接引用这些常量。

需要特别注意的是,在接口中不能有实例域或者静态方法(静态一般都跟类相关,而跟接口无关),也不能有方法实现。

跟抽象类一样,不能实例化接口,但是可以声明接口的对象变量,然后将实现接口的类对象赋值给他。例如:
[java]   view plain copy
  1. List<String> strings = new ArrayList<String>();  

可以使用instanceof检查某个对象是否属于一个类,也可以检查一个对象是否实现类某个接口,例如
[java]   view plain copy
  1. if (anObjecy instanceof Comparable)  

接口跟抽象类最大的区别除了抽象类可以含有实例域和实例方法(而接口不行)以外,Java中只能使用单继承,但是却可以实现多个接口,这是很重要的一个特性。

你可能感兴趣的:(java 抽象类和接口)