1. 程式人生 > >thinking in java (三) ----- 介面與抽象類

thinking in java (三) ----- 介面與抽象類

 

 

介面的抽象類給我們提供了介面和實現分離更加結構化的方法

介面和抽象類是java中對抽象概念進行定義的兩種機制,正是因為他們的存在,才賦予了java強大的面向物件的能力。他們之間對於抽象有很大的相似,但是也有一些不同

抽象類

前面我們說過萬物皆物件,物件是通過類來描述的,但並不是所有的類都是用來描述物件的。如果一個類沒有足夠的資訊來描述一個具體的物件,而需要其他具體的類來支撐它,那麼這樣的類我們稱為抽象類

比如new Car(),但是具體的car長什麼樣,我們是不知道的,是抽象類。我們需要一個具體的車,比如卡宴,寶馬等進行特定描述。

抽象類體現了抽象的思想,是實現多型的一種機制,他定義了一組抽象方法,其中的具體形式通過子類來實現。抽象類會被繼承,否則其沒有存在的意義。使用抽象類時,需要注意以下幾點:

  1. 抽象類不能被實體化,只需要提供一個引用就行了
  2. 抽象方法由子類進行重寫
  3. 只要有一個抽象方法,這個類就是抽象類
  4. 子類中的抽象方法不能和父類中的抽象方法一樣
  5. 抽象方法也可以有具體方法,可以有成員變數
  6. abstract修飾的方法就是需要被重寫,因此不能跟static,private並列修飾一個方法

例項

定義一個動物類Aninal,提供抽象方法cry(),貓狗為子類,如下:

public abstract class Animal {
    public abstract void cry();
}

public class Cat extends Animal{

    @Override
    public void cry() {
        System.out.println("貓叫:喵喵...");
    }
}

public class Dog extends Animal{

    @Override
    public void cry() {
        System.out.println("狗叫:汪汪...");
    }

}

public class Test {

    public static void main(String[] args) {
        Animal a1 = new Cat();
        Animal a2 = new Dog();
        
        a1.cry();
        a2.cry();
    }
}

--------------------------------------------------------------------
Output:
貓叫:喵喵...
狗叫:汪汪...

介面

關鍵字interface將abstract的概念做了更進一步的發揮,可以想象它是純粹的abstract class,他構建出class(函式名,引數列表 返回型別)的形式,但是沒有方法體。interface中可以含有資料成員,但是自然而然成為static final。interface值提供形式,不實現細節。

介面是抽象類的延伸,介面優於抽象類的一點是能夠多實現,彌補了抽象類不能多繼承的缺陷。在使用介面的過程中,需要注意一下問題:

  1. interface中的所有方法都會被自動宣告為public,且只能為public
  2. 介面中可以宣告變數,但是是靜態變數
  3. 介面中不存在實現的方法
  4. 實現介面的非抽象類必須實現介面中所有的方法
  5. 介面不能被例項化
  6. 在實現多介面的時候注意避免方法名的重複

抽象類的介面的區別

1,語法層次

在語法層次,兩者定義不同。下面使用程式碼來說明不同之處。

抽象類:

public abstract class Demo {
    abstract void method1();
    
    
    void method2(){
        //實現
    }
}

介面:

interface Demo {
    void method1();
    void method2();
}

抽象類方式中,抽象類可以擁有任意範圍的成員資料,同時也可以擁有自己的非抽象方法,但是介面方式中,它僅能夠有靜態、不能修改的成員資料(但是我們一般是不會在介面中使用成員資料),同時它所有的方法都必須是抽象的。在某種程度上來說,介面是抽象類的特殊化。

對子類而言,它只能繼承一個抽象類(這是java為了資料安全而考慮的),但是卻可以實現多個介面。

2,設計層次

從設計層次上來講,才能看出兩者本質的差別

1,抽象層次不同。抽象類時對類抽象,介面是對行為的抽象。抽象類時是對類整體抽象,包括行為屬性,但是interface只是對行為進行抽象

2,跨域不同,抽象類體現的 是一種繼承關係,父類的子類必須是is-a關系,父類和子類本質上是相同的。interface則不是,interface只是是實現者對行為的實現,比如說飛機和鳥實現飛的行為

3,設計層次不同。抽象類時自下而上設計的,我們要先知道子類才能抽象出父類,而介面不需要知道子類的存在,只需要定義規則就行。

區別的例子

定義一個phone的類,裡面有打電話的方法,所有的手機都會有打電話的功能。

抽象類

abstract class Phone{
    abstract void call();
    
}

介面 

interface Phone{
    void call();
}

現在增加一個功能“上網”surf,

抽象類變成了:

abstract class Phone{
    abstract void call();
    abstract void surf();
    
}

介面變為:

interface Phone{
    void call();
    void surf();
}

 但是這樣就有些問題出現了,phone中除了固定有的方法外還混進去了一個 surf功能,這樣依賴於phone模組的就必學會上網,但是每個手機不一定都能上網(老年機)。這樣就違反了設計原則,介面汙染。

解決方法

一個使用介面,一個使用抽象類

abstract class Door{
    abstract void open();
    abstract void close();
}

interface Alarm{
    void alarm();
}

class AlarmDoor extends Door implements Alarm{
    void open(){}
    void close(){}
    void alarm(){}
}

這種實現方式基本上能夠明確的反映出我們對於問題領域的理解,正確的揭示我們的設計意圖。其實抽象類表示的是"is-a"關係,介面表示的是"like-a"關係。

總結

  • 抽象類表示的是一種繼承關係,只能單繼承。介面表示的是一種行為規範,可以實現多個介面
  • 抽象類可以擁有自己的成員變數和非抽象方法,介面中只能有靜態常量,所有的方法都沒有實現的
  • 抽象類和介面的設計理念是不一樣的,抽象類體現的是is-a關係,而介面代表的是like-a關係

抽象類和介面是java中兩種不同的抽象概念,他們的存在對多型提供了好的支援,雖然他們之間語法上有很多相似性,但是他們的設計上往往體現了對問題的理解。只有對問題更好理解,才能更好設計介面和抽象類。

 

參考資料:作者: chenssy 
出處: http://www.cnblogs.com/chenssy/