首頁 Java java教程 Java 抽象類別與介面

Java 抽象類別與介面

Dec 05, 2016 pm 01:34 PM
java 抽象類別 介面

Java 抽象類別

我們父類別設定了一些方法,設定的主要目的是讓子類別繼承父類別去覆寫那些方法,來展示不同的結果。換句話說,我們不關心父類別方法裡的具體實現,反正會被子類別的方法覆寫,那麼我們就可以讓父類別更抽像一下,抽像到只有方法的聲明,而沒有方法體。我們管這種方法叫做抽象方法,管包含抽象方法的類別叫做抽象類別。

抽象類別的特徵

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

[public] abstract 返回類型方法名(參數列表); 
抽象方法是沒有方法體的,所以方法名寫完就會加;表示方法聲明結束,抽像法方法體用abstract修飾,表示這是一個抽象的方法,存取修飾符只能用public或protected,或是預設存取權限,就是不能用private,因為根本無法去繼承 
同樣,抽象類別的格式如下:

[public] abstract class 类名{
    [public] abstract 返回类型 方法名(参数列表);
}
登入後複製

抽象類別的是前面加abstract修飾,表示這個是抽象類,存取修飾符只能用public或是protected,或是預設存取權限,不能用private的原因跟上面一樣。 
抽象類別創造的意義是將方法的宣告與方法的實作分隔開,從而實現多態。那麼他就具有如下的特點:

抽象類別不能被實例化,也就是說不能直接創建一個抽象類別的對象,但抽象類別是可以有建構函數的,如果是有參構造函數,則子類別要去顯示調用它。
抽象類別是用來被繼承的,方法是要被覆寫的,如果子類別繼承了抽象的父類,則需要覆寫父類別的抽象方法,如果沒有覆寫,則子類別必須也要定義為抽象類別。 
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{
}
登入後複製

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

一个类是可以实现多个接口的,这在一定程度上实现了Java的多继承。
接口是不能被实例化,不同于抽象类,接口的内部只能由成员变量和抽象方法,是不可以存在静态变量块,以及构造器的。
我们是可以声明一个接口类型的变量,但是只能引用一个实现了这个接口的类。
同抽象方法,实现了接口的类必须实现接口的所有方法,否则就会变成抽象类。
接口举例

看过抽象的例子,我们可能想,我们把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);
    }
}
登入後複製

接口总结

接口和抽象虽然都是通过抽象的方法来提供我们实现多态的方式,但是他们却是两个不同的设计思想。这里关于接口的讲解比较简单,关于接口自身的继承,接口内部包含其他接口,以及利用接口来实现回调等等留在以后的文章专门来说。这里主要是通过对比来了解抽象和接口。


本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

AI Hentai Generator

AI Hentai Generator

免費產生 AI 無盡。

熱門文章

R.E.P.O.能量晶體解釋及其做什麼(黃色晶體)
3 週前 By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.最佳圖形設置
3 週前 By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.如果您聽不到任何人,如何修復音頻
3 週前 By 尊渡假赌尊渡假赌尊渡假赌
WWE 2K25:如何解鎖Myrise中的所有內容
3 週前 By 尊渡假赌尊渡假赌尊渡假赌

熱工具

記事本++7.3.1

記事本++7.3.1

好用且免費的程式碼編輯器

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

禪工作室 13.0.1

禪工作室 13.0.1

強大的PHP整合開發環境

Dreamweaver CS6

Dreamweaver CS6

視覺化網頁開發工具

SublimeText3 Mac版

SublimeText3 Mac版

神級程式碼編輯軟體(SublimeText3)

Java 中的平方根 Java 中的平方根 Aug 30, 2024 pm 04:26 PM

Java 中的平方根指南。下面我們分別透過例子和程式碼實作來討論平方根在Java中的工作原理。

Java 中的完美數 Java 中的完美數 Aug 30, 2024 pm 04:28 PM

Java 完美數指南。這裡我們討論定義,如何在 Java 中檢查完美數?

Java 中的阿姆斯壯數 Java 中的阿姆斯壯數 Aug 30, 2024 pm 04:26 PM

Java 中的阿姆斯壯數指南。這裡我們討論一下java中阿姆斯壯數的介紹以及一些程式碼。

Java 中的隨機數產生器 Java 中的隨機數產生器 Aug 30, 2024 pm 04:27 PM

Java 隨機數產生器指南。在這裡,我們透過範例討論 Java 中的函數,並透過範例討論兩個不同的生成器。

Java中的Weka Java中的Weka Aug 30, 2024 pm 04:28 PM

Java 版 Weka 指南。這裡我們透過範例討論簡介、如何使用 weka java、平台類型和優點。

Java 中的史密斯數 Java 中的史密斯數 Aug 30, 2024 pm 04:28 PM

Java 史密斯數指南。這裡我們討論定義,如何在Java中檢查史密斯號?帶有程式碼實現的範例。

Java Spring 面試題 Java Spring 面試題 Aug 30, 2024 pm 04:29 PM

在本文中,我們保留了最常被問到的 Java Spring 面試問題及其詳細答案。這樣你就可以順利通過面試。

突破或從Java 8流返回? 突破或從Java 8流返回? Feb 07, 2025 pm 12:09 PM

Java 8引入了Stream API,提供了一種強大且表達力豐富的處理數據集合的方式。然而,使用Stream時,一個常見問題是:如何從forEach操作中中斷或返回? 傳統循環允許提前中斷或返回,但Stream的forEach方法並不直接支持這種方式。本文將解釋原因,並探討在Stream處理系統中實現提前終止的替代方法。 延伸閱讀: Java Stream API改進 理解Stream forEach forEach方法是一個終端操作,它對Stream中的每個元素執行一個操作。它的設計意圖是處

See all articles