更新時(shí)間:2023-05-16 來(lái)源:黑馬程序員 瀏覽量:
在Java中,abstract class和interface都是用來(lái)定義抽象類型的關(guān)鍵字,但它們?cè)谡Z(yǔ)法上有幾個(gè)重要的區(qū)別:
abstract class是一種類,可以定義構(gòu)造函數(shù)、成員變量和非抽象方法,也可以包含抽象方法,而interface只能定義常量和抽象方法,不能包含任何具體的實(shí)現(xiàn)。
一個(gè)類可以繼承多個(gè)接口,但只能繼承一個(gè)抽象類。此外,抽象類可以作為其他類的基類,而接口不能。
在抽象類中可以定義抽象方法,它們必須在非抽象子類中實(shí)現(xiàn)。在接口中定義的所有方法都是抽象的,實(shí)現(xiàn)接口的類必須提供方法的實(shí)現(xiàn)。
從Java 8開(kāi)始,接口可以定義默認(rèn)方法,這些方法具有默認(rèn)實(shí)現(xiàn),可以被實(shí)現(xiàn)接口的類直接繼承或覆蓋。抽象類也可以定義具有默認(rèn)實(shí)現(xiàn)的方法,但是默認(rèn)實(shí)現(xiàn)必須是非抽象的。
在抽象類中可以定義非常量成員變量,而在接口中只能定義常量(static final)變量。
接下來(lái),筆者用一段Java代碼來(lái)詳細(xì)演示下abstract class和interface之間的語(yǔ)法區(qū)別:
// 抽象類 abstract class Animal { String name; public Animal(String name) { this.name = name; } // 抽象方法,必須在非抽象子類中實(shí)現(xiàn) abstract void makeSound(); // 非抽象方法,可以在抽象類中直接實(shí)現(xiàn) public void sleep() { System.out.println(name + " is sleeping."); } } // 接口 interface Swimable { // 常量 int MAX_SPEED = 10; // 抽象方法 void swim(); } // 實(shí)現(xiàn)接口的類 class Fish implements Swimable { // 必須實(shí)現(xiàn)接口中定義的所有方法 public void swim() { System.out.println("Fish is swimming."); } } // 繼承抽象類的子類 class Dog extends Animal { public Dog(String name) { super(name); } // 必須實(shí)現(xiàn)父類中定義的抽象方法 void makeSound() { System.out.println(name + " is barking."); } } public class Main { public static void main(String[] args) { Animal animal = new Dog("Puppy"); animal.makeSound(); animal.sleep(); Swimable swimable = new Fish(); swimable.swim(); System.out.println("Max speed: " + Swimable.MAX_SPEED); } }
在這個(gè)例子中,Animal是一個(gè)抽象類,它有一個(gè)非抽象方法sleep和一個(gè)抽象方法makeSound。Swimable是一個(gè)接口,它定義了一個(gè)常量MAX_SPEED和一個(gè)抽象方法swim。Fish實(shí)現(xiàn)了Swimable接口,并提供了swim方法的具體實(shí)現(xiàn)。Dog是Animal的子類,它實(shí)現(xiàn)了makeSound方法,并繼承了sleep方法。在Main類中,我們創(chuàng)建了一個(gè)Dog對(duì)象和一個(gè)Fish對(duì)象,并調(diào)用了它們的方法。注意到在Swimable.MAX_SPEED這一行,我們直接通過(guò)接口名訪問(wèn)了接口中定義的常量。