天天看點

java基礎提高篇--抽象類和接口

抽象類和接口是java語言中對抽象概念進行定義的兩種機制,這兩種機制展現的java面向對象的強大之處。抽象類和接口對于抽象概念的支援是相似的,可以互相轉換,但是也是有差別的。

一、抽象類

我麼知道在面向對象中,萬事萬物皆對象,同時所有的對象都是通過類來描述的,而不是所有的類是用來描述對象的。如果一個類不能描述具體的對象,而是通過其他來支撐的,那個這個類就是抽象類。比如有一個Animal類,它具體是什麼動物我們不知道,是以它不是一個具體動物的類。我們需要Dog,Cat這些具體的來實作它,我們才知道動物具體的是什麼。

在面向對象的領域,沒有具體的概念。抽象類具有抽象的概念,它沒有具體的實作方法,是通過它派生出來的類來實作的。所有繼承是抽象類的出發點,沒有繼承的話,抽象類就沒有存在的意義。

    抽象類在使用中需要注意以後幾點:

(1)、抽象類不能被執行個體化,通過它的子類來實作執行個體化,它隻需要一個引用即可;

(2)、如果一個類中有抽象方法,那麼這個類必須定義成抽象類,這個抽象類還可以有其他的方法;

(3)、一個抽象類,可以沒有抽象方法;

(4)、抽象類的抽象方法必須由子類來重寫;

(5)、abstract不能與final并列修飾一個類;

(6)、abstract不能與private、static、final和native并列修飾一個方法。

執行個體:

Aniaml.java

package test1;

/**
 * Created by Administrator on 2017/5/8.
 */
public abstract class Animal  {
    public abstract void like();
}      

Cat.java

package test1;

/**
 * Created by Administrator on 2017/5/8.
 */
public class Cat extends Animal {
    @Override
    public void like() {
        System.out.println("Cat說:我好愛吃魚!");
    }
}      

Dog.java

package test1;

/**
 * Created by Administrator on 2017/5/8.
 */
public class Dog extends Animal {
    @Override
    public void like() {
        System.out.println("Dog說:我好愛吃骨頭!");
    }
}      

Test.java

package test1;

/**
 * Created by Administrator on 2017/5/8.
 */
public class Test {
    public static void main(String[] args) {
        Animal adog=new Dog();
        Animal acat=new Cat();
        adog.like();
        acat.like();
    }
}      

輸出:Dog說:我好愛吃骨頭!

   Cat說:我好愛吃魚!

上面的列子可以看出,抽象的抽象方法由子類來重寫,執行個體化工作也是由子類來完成的,他隻是一種引用,是多态的一種機制。正如《Think in Java》書中講的,建立抽象類和抽象方法是非常有用的,因為它麼使抽象性明确起來,告知使用者和編譯器打算怎樣使用它們。抽象類也是很有用的重構器,因為它們很容易的将公共方法沿着繼承層次結構向上轉移。

二、接口

接口是一種比抽象類更加抽象的“類”,這裡的類加上了雙引号,因為我不知道用什麼詞語來修飾,但是要明确一點的就是接口本身不是類,從它不能執行個體化一點就可以看出來了。我們隻能執行個體化接口的實作類。

接口是用來建立類與類之間的聯系,它隻是一種表現形式,而沒有具體的實作。同時實作該接口的實作類必須實作該接口的裡面的所有的方法,通過implements關鍵字,它表示該類遵循一個或一組特定的接口,同時表示“interface隻是它的外貌,但是現在要申明它是怎麼工作的”。

java中為了保證資料的安全性,繼承隻能是單繼承,也就是一個子類之能有一個父類,而接口正好彌補了這一缺陷,一個類可以實作一個接口也可以同時實作多個接口。在實際的工作中,建議繼承和接口同時使用,這樣既保證了資料的安全性又實作了多重繼承。

在使用接口的過程中注意一下幾個問題:

(1)、一個接口中所有方法都申明成public,也就是隻能是public,如果申明成private或者proteced,那麼就會報錯;

(2)、一個接口中沒有具體的實作方法;

(3)、一個接口中可以申明“成員變量”,就是不可變的量,也就是申明的變量預設的修飾為public static final;

(4)、實作該接口的非抽象類必須實作該接口的所有方法,抽象類無需這樣;

(5)、不能使用new執行個體化一個接口,但是可以申明一個變量,這個變量必須引用實作該類的對象。可以使用instance of來檢查一個對象是否實作了接口;

(6)、一個類實作多個接口的還是要注意方法名不能同名。

三、接口和抽象的差別

雖然抽象類和接口兩者之間有很大的相似之處,有時可以互相替換,但是它們還是由差異之處,我們将從文法層次和設計層次兩個方面來闡述。

1、文法層次:

抽象類和接口在語言層次上,Java給出了不同定義,下面看具體代碼:

java基礎提高篇--抽象類和接口
java基礎提高篇--抽象類和接口

從上述代碼中可以看出,抽象類中可以有抽象方法也可以有非抽象方法,可以定義任何範圍的成員資料,而接口中的方法必須都是抽象的,并且隻能定義靜态的成員資料(一般不定義);

 對子類而言,隻能有一個父類,而可以實作多個接口。

  (2)、設計層次

上面隻是從文法層次和程式設計角度來區分它們之間的關系,這些都是低層次的,要真正使用好抽象類和接口,我們

就必須要從較高層次來區分了。隻有從設計理念的角度才能看出它們的本質所在。一般來說他們存在如下三個不同點:

      1、 抽象層次不同。抽象類是對類抽象,而接口是對行為的抽象。抽象類是對整個類整體進行抽象,包括屬性、

行為,但是接口卻是對類局部(行為)進行抽象。

      2、 跨域不同。抽象類所跨域的是具有相似特點的類,而接口卻可以跨域不同的類。我們知道抽象類是從子類中

發現公共部分,然後泛化成抽象類,子類繼承該父類即可,但是接口不同。實作它的子類可以不存在任何關系,共同之處。例如貓、狗可以抽象成一個動物類抽象類,具備叫的方法。鳥、飛機可以實作飛Fly接口,具備飛的行為,這裡我們總不能将鳥、飛機共用一個父類吧!是以說抽象類所展現的是一種繼承關系,要想使得繼承關系合理,父類和派生類之間必須存在"is-a" 關系,即父類和派生類在概念本質上應該是相同的。對于接口則不然,并不要求接口的實作者和接口定義在概念本質上是一緻的, 僅僅是實作了接口定義的契約而已。

      3、 設計層次不同。對于抽象類而言,它是自下而上來設計的,我們要先知道子類才能抽象出父類,而接口則不

同,它根本就不需要知道子類的存在,隻需要定義一個規則即可,至于什麼子類、什麼時候怎麼實作它一概不知。比

如我們隻有一個貓類在這裡,如果你這是就抽象成一個動物類,是不是設計有點兒過度?我們起碼要有兩個動物類,

貓、狗在這裡,我們在抽象他們的共同點形成動物抽象類吧!是以說抽象類往往都是通過重構而來的!但是接口就不

同,比如說飛,我們根本就不知道會有什麼東西來實作這個飛接口,怎麼實作也不得而知,我們要做的就是事前定義

好飛的行為接口。是以說抽象類是自底向上抽象而來的,接口是自頂向下設計出來的。