之所以將抽象類和介面放在一起做筆記,是因為他們之間很難區分又各自獨立。在學習完Java程式設計的三大特點(封裝、繼承、多態)之後,我最大的收穫是,慢慢理解了Java語言這種面向對象程式設計的優越性,它既能保持自身獨立性又在不斷進化、發展的。如果說封裝和繼承是實現Java多態性的基礎,那我個人覺得抽象 ...
之所以將抽象類和介面放在一起做筆記,是因為他們之間很難區分又各自獨立。在學習完Java程式設計的三大特點(封裝、繼承、多態)之後,我最大的收穫是,慢慢理解了Java語言這種面向對象程式設計的優越性,它既能保持自身獨立性又在不斷進化、發展的。如果說封裝和繼承是實現Java多態性的基礎,那我個人覺得抽象類和介面更是為多態提供了非常好的支持。
一、抽象類
從形式上來說,用abstract修飾的類就是抽象類。抽象類是不完整的,只能做基類,且不能夠實例化(不能new)。
通俗來講,抽象類它本身不做任何事情,它是去要求別人來實現它的規範的。它定義了一組抽象的方法,至於這組抽象方法的具體表現形式有派生類來實現。抽象類的實現要用到繼承,不然你造出來它就沒有意義。
使用抽象類必須註意以下幾點:
1.抽象類只是一個引用而已,不能被實例化,實例化的工作要交給它的子類;
2.抽象方法必須由子類來進行重寫;
3.在一個類中,只要有一個方法被定義為抽象方法(被abstract修飾了),那麼這個類就必須被定義為抽象類(類名也要被abstract修飾);
4.抽象類中可以包含具體方法,也可以不包含;
1 public abstract class ChouX { 2 public abstract void method1(); 3 4 public void method2() { 5 6 } 7 }
5.子類中的抽象方法不能與父類的抽象方法同名;
6.abstract不能與private、static、fanal或native併列修飾同一個方法。
代碼實例:
//抽象類 public abstract class Animal { public abstract void shout(); }
1 //貓子類 2 public class Cat extends Animal { 3 public void shout() { 4 System.out.println("喵~~"); 5 } 6 }
//Dog子類 public class Dog extends Animal { public void shout() { System.out.println("汪汪汪。。。"); } }
//測試類 public class Test { public static void main(String[] args) { Animal a1 = new Dog(); Animal a2 = new Cat(); a1.shout(); a2.shout(); } }
Output:
二、介面
對於面向對象編程來說,抽象是它的一大特征。在java中,可以通過兩種形式來體現OOP的抽象:抽象類和介面。
介面(interface),在軟體工程中,介面泛指供別人調用的方法或者函數。
格式:
[public] interface InterfaceName{ }
//例子
interface Door{ public abstract void open(); public abstract void close(); }
要讓一個類遵循某組特定地介面需要使用implements關鍵字。
格式:
class ClassName implements Interface1,Interface2,Interface3....{}(允許一個類遵循多個特定的介面)
三、抽象類和介面的區別
1.語法層面的區別
首先,抽象類可以提供成員方法實現的細節,而介面中只能存在public abstract 方法;
其次,抽象類中的成員變數可以是各種類型的,而介面中的成員只能是public static final類型的;
再者,介面中不能含有靜態代碼塊和靜態方法,而抽象類可以;
最後,一個類只能繼承一個抽象類,而可以繼承多個介面。
2.設計層面上的區別
首先,抽象類是對一種事物的抽象,即對類的抽象,而介面是對行為的抽象。
再者,抽象類作為很多子類的父類,它是一種模板式的設計。而介面是一種行為規範。
最後,在一個抽象類中,如果你想更改一個方法,可以直接在抽象類中實現,子類可以不進行更改。而這種事情發生在介面上,那麼所有鏈接這個介面的類都需要更改。
總結:說了這麼多,其實原理只要想通了還是蠻簡單的。對於抽象類,就比如說,你定義一個抽象類,來做父類。你有可能對一個類的描述就沒寫全,或者它幾年以後升級換代了。那也總有保留的吧。這時候你不必大動干戈把整個父類統統推翻,你只需要在子類中填上具體的更改的方式就可以了。想改什麼不改什麼,什麼時候改都由你自己決定。這樣靈活性、重用性是不是就高了。而抽象類與介面的區別,就像魚和船都能在水裡游吧,那他們也不是同一個類啊。你也就別想著把魚和船划到一個類當中,但是這個“游”的動作是它們都有的,我們就把這個“游”的動作設置成一個介面,魚能用,船能用,將來你想描述任何會“游”的事物的時候都可以用上它。
網上有個很有取的案例:
可以好好思考一下,方便形象理解抽象類和介面的區別。
1 //介面 2 interface Alram{ 3 void alarm(); 4 }
1 //抽象類 2 abstract class Door{ 3 void open(); 4 void close(); 5 }
1 //報警門最後的設置 2 class AlarmDoor extends Door implements Alarm{ 3 void open(){ 4 } 5 void close(){ 6 } 7 void alarm(){ 8 } 9 }