歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
Linux教程網 >> Linux編程 >> Linux編程 >> Java 抽象類與接口

Java 抽象類與接口

日期:2017/3/1 9:14:07   编辑:Linux編程

Java 抽象類

在上文我們的多態的講解中(見 http://www.linuxidc.com/Linux/2016-07/133308p3.htm),我們父類設定了一些方法,設定的主要目的是讓子類繼承父類去覆寫那些方法,來展示不同的結果。換句話說,我們不關心父類方法裡的具體實現,反正會被子類的方法覆寫,那麼我們就可以讓父類更抽象一下,抽象到只有方法的聲明,而沒有方法體。我們管這種方法叫做抽象方法,管包含抽象方法的類叫做抽象類。

抽象類的特點

抽象類裡只要含有一個或者一個以上的抽象方法就是抽象類,但如果一個抽象方法都沒有,那這個抽象類也沒有建立的意義。抽象方法是具有如下格式的方法

[public] abstract 返回類型 方法名(參數列表);

抽象方法是沒有方法體的 ,所以方法名寫完就會加;表示方法聲明結束,抽象法方法體用abstract修飾,表示這是一個抽象的方法,訪問修飾符只能用public或者是protected,或者是默認訪問權限,就是不能用private,因為根本無法去繼承
同樣,抽象類的格式如下:

[public] abstract class 類名{
    [public] abstract 返回類型 方法名(參數列表);
}

抽象類的是前面加abstract修飾,表示這個是一個抽象類,訪問修飾符只能用public或者是protected,或者是默認訪問權限,不能用private的原因和上面一樣。
抽象類創造的意義是將方法的聲明與方法的實現分隔開,從而實現多態。那麼他就具有如下的特點:

  1. 抽象類不能被實例化,也就是說不能直接創建一個抽象類的對象,但抽象類是可以有構造函數的,如果是有參構造函數,則子類要去顯示調用它。
  2. 抽象類是用來被繼承的,方法是要被覆寫的,如果子類繼承了抽象的父類,則需要覆寫父類的抽象方法,如果沒有覆寫,則子類必須也要定義為抽象類。
  3. abstract是不能與private static,final 修飾符一起使用來修飾方法。

    這裡我們解釋一下第三點,abstract不能與private一起用,因為private修飾的方法和類,都是無法再類之外被訪問到。也就沒有繼承的可能性。abstract不能和static一起用,是因為abstract的作用是實現多態,而實現多態則依賴於繼承和覆寫。static修飾的方法雖能被子類所繼承,但是我們修改了繼承後的方法時,這個就不能算作是覆寫,而是父類的方法被隱藏掉了,只有通過父類名.方法名的形式顯示調用它,這個實現不了多態。從另一個角度來看,靜態的方法是編譯的時候就確定了,無法實現後期綁定,也就不存在運行時在決定方法調用的可能。所以static修飾的方法是可以被繼承,但無法實現多態,自然也就不能和abstract一起使用。
    abstract不能和final一起使用的原因和上面一樣,final修飾的方法無法被繼承,自然也談不上多態,所以abstract無法和final一起用。

抽象類舉例

我們把上文多態的例子,繼續修改,抽象化。我們把Animal的代碼改成如下樣子。

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

我們Dog,Cat類的代碼不需要改變。

public class Dog extends Animal{
    @Override
    public void run() {
        System.out.println("狗在奔跑");
    }
}

public class Cat extends Animal{

    @Override
    public void run() {
        System.out.println("貓在奔跑");
    }
}

其他Print類,和Test類的代碼也保持不變,代碼如下:

public class Print {
    public void print(Animal animal) {
        animal.run();
    }
}

public class Test {
    public static void main(String[] args) {
        Animal dog = new Dog();
        Animal cat = new Cat();
        new Print().print(dog);
        new Print().print(cat);
    }
}

我們可以看出抽象類和之前普通類,在其他地方的改動基本是沒有的,只是將方法變得抽象,意義上更加明確。

抽象總結

創建抽象類和抽象方法是很有意義的,他能讓我們設計類的時候使類的含義更加明確,通過抽象的思想,讓類變得更加通用,聲明一系列的方法來告訴用戶打算怎麼去使用它。

Java 接口

接口可以看出一種協議,一種要求,我們繼承他來知道我們可以做什麼,具體怎麼做則取決與我們。比如KFC就是一個接口,我們一看他就知道裡面有買漢堡,炸雞,可樂,但是具體的味道和服務又會根據不同的店,有不同的樣子,這就是接口的意義。所以我們這裡也可以看出接口裡的方法也應該是抽象的。

接口的特點

Java中接口的寫法如下:

[public] interface InterfaceName {
         成員變量
         方法聲明
}

接口區別於類,他不是用class來修飾,他用特定的interface關鍵字,訪問修飾符與class一致,可以用public或者缺省。裡面只有抽象方法和成員變量兩種內容。成員變量會默認添加public static final意為成員變量歸類所有,訪問權限是最大的,但是不能別繼承和修改。這也看出接口是因為不能被實例化,才會這樣約定的,接口的成員變量不允許為空,在定義的時候就要賦值給他。 而接口的方法則默認為抽象方法,默認添加public abstract和抽象方法一樣,只能寫方法聲明。
不同於我們用extends去繼承一個類,我們用implements 來表示實現這個接口。

class ClassName implements Interface1{
}

接口作為一個特殊的存在,是有一些他的獨特的地方的。

  1. 一個類是可以實現多個接口的,這在一定程度上實現了Java的多繼承。
  2. 接口是不能被實例化,不同於抽象類,接口的內部只能由成員變量和抽象方法,是不可以存在靜態變量塊,以及構造器的。
  3. 我們是可以聲明一個接口類型的變量,但是只能引用一個實現了這個接口的類。
  4. 同抽象方法,實現了接口的類必須實現接口的所有方法,否則就會變成抽象類。

接口舉例

看過抽象的例子,我們可能想,我們把Animal從抽象換成接口,不就實現了一個接口的例子嘛,其他地方基本也不用去改動。但這顯然是錯的。我們並不能去說Animal是一個接口,我們上面說了,接口是一種協議,規定我們能做什麼,而不是一個事物的抽象。從這裡我們也能看出接口和抽象的不同,抽象更多的是一種重構而產生的東西,我們先有dog,cat類,然後才會把他們共性的東西提取出來,放到一個更通用,更抽象的父類Animal中,而我們發現Animal不需要管run方法是怎麼實現的,所以我們將run方法設定為抽象的方法,從而將Animal類設為抽象類,等待去=繼承者來實現run。這是一種從下而上的設計思想。但是接口不是,接口一開始就是設定好的,我們根據設定好的接口從上往下去寫。接口先規定好了有什麼方法,然後我們再去具體實現他。這是一種從上而下的設計思想。
所以,我們不能將Animal設為接口,但是我們可以將Print設為接口,他規定我們有一個print()方法,代碼如下:

public interface Print {
    void print(Object obj);
}

那我們就可以寫一個新的類去實現這個Print接口。代碼如下:

public class SimplePrint implements Print{

    @Override
    public void print(Object obj) {
        ((Animal)obj).run();
    }
}

除了Test類以外,其他地方都不需要改變。我們Test類代碼如下:

public class Test {
    public static void main(String[] args) {
        Animal dog = new Dog();
        Animal cat = new Cat();
        Print print = new SimplePrint();
        print.print(dog);
        print.print(cat);
    }
}

接口總結

接口和抽象雖然都是通過抽象的方法來提供我們實現多態的方式,但是他們卻是兩個不同的設計思想。這裡關於接口的講解比較簡單,關於接口自身的繼承,接口內部包含其他接口,以及利用接口來實現回調等等留在以後的文章專門來說。這裡主要是通過對比來了解抽象和接口。

Copyright © Linux教程網 All Rights Reserved