在本教程中,我們將學(xué)習(xí)Java中的抽象。我們將學(xué)習(xí)Java抽象類(lèi)和方法,以及如何在程序中使用它們。
抽象類(lèi)是無(wú)法實(shí)例化的類(lèi)(我們無(wú)法創(chuàng)建抽象類(lèi)的對(duì)象)。在Java中,我們使用abstract關(guān)鍵字聲明一個(gè)抽象類(lèi)。
abstract class Animal { //屬性和方法 }
如果嘗試創(chuàng)建抽象類(lèi)的對(duì)象,則會(huì)出現(xiàn)編譯錯(cuò)誤。例如,
Animal a1 = new Animal()
它將產(chǎn)生一個(gè)編譯錯(cuò)誤:
Animal is abstract; cannot be instantiated
盡管不能實(shí)例化抽象類(lèi),但是我們可以從中創(chuàng)建子類(lèi)。我們可以創(chuàng)建子類(lèi)的對(duì)象來(lái)訪(fǎng)問(wèn)抽象類(lèi)的成員。
在詳細(xì)了解它之前,我們需要了解抽象方法。
我們使用相同的關(guān)鍵字abstract來(lái)創(chuàng)建抽象方法。聲明了一個(gè)抽象方法而沒(méi)有實(shí)現(xiàn)。例如,
abstract void makeSound();
在這里,makeSound()是一種抽象方法。
重要的是要注意,只有一個(gè)抽象類(lèi)才能包含抽象方法。如果我們?cè)诓皇浅橄蟮念?lèi)中包含抽象方法,則會(huì)出現(xiàn)錯(cuò)誤。抽象類(lèi)可以包含抽象方法和非抽象方法。這是一個(gè)實(shí)例。
abstract class Animal { public void displayInfo() { System.out.println(“I am an animal.”); } abstract void makeSound(); }
在上面的示例中,我們創(chuàng)建了一個(gè)抽象類(lèi)Animal。它包含一個(gè)抽象方法makeSound()和一個(gè)非抽象方法displayInfo()。
抽象類(lèi)無(wú)法實(shí)例化。要訪(fǎng)問(wèn)抽象類(lèi)的成員,我們必須繼承它。例如
abstract class Animal { public void displayInfo() { System.out.println("I am an animal."); } } class Dog extends Animal { } class Main { public static void main(String[] args) { Dog d1 = new Dog(); d1.displayInfo(); } }
輸出:
I am an animal.
在上面的示例中,我們創(chuàng)建了一個(gè)抽象類(lèi)Animal。我們不能創(chuàng)建Animal類(lèi)的對(duì)象。為了訪(fǎng)問(wèn)Animal類(lèi)中的displayInfo()方法,我們繼承了Animal的子類(lèi)Dog。
然后,我們使用Dog的d1對(duì)象訪(fǎng)問(wèn)該displayInfo()方法。
在Java中,必須在子類(lèi)中重寫(xiě)超類(lèi)的抽象方法。這是因?yàn)樽宇?lèi)繼承了超類(lèi)的抽象方法。
因?yàn)槲覀兊淖宇?lèi)包含抽象方法,所以我們需要重寫(xiě)它們。
注意:如果子類(lèi)也被聲明為抽象,則不必強(qiáng)制重寫(xiě)抽象方法。
abstract class Animal { abstract void makeSound(); public void eat() { System.out.println("I can eat."); } } class Dog extends Animal { public void makeSound() { System.out.println("Bark bark"); } } class Main { public static void main(String[] args) { Dog d1 = new Dog(); d1.makeSound(); d1.eat(); } }
輸出:
Bark bark. I can eat.
在上面的示例中,我們創(chuàng)建了一個(gè)抽象類(lèi)Animal。該類(lèi)包含一個(gè)抽象方法makeSound()和一個(gè)非抽象方法eat()。
我們從超類(lèi)Animal繼承了一個(gè)子類(lèi)Dog。這里,子類(lèi)Dog覆蓋了抽象方法displayInfo()。
然后我們創(chuàng)建了Dog的對(duì)象d1。使用該對(duì)象,我們調(diào)用了d1.displayInfo()和d1.eat()方法。
與非抽象類(lèi)相似,我們使用super關(guān)鍵字從子類(lèi)訪(fǎng)問(wèn)抽象類(lèi)的構(gòu)造函數(shù)。例如,
abstract class Animal { Animal() { …. } } class Dog extends Animal { Dog() { super(); ... } }
在這里,我們使用Dog的構(gòu)造函數(shù)中的super()訪(fǎng)問(wèn)Animal類(lèi)的構(gòu)造函數(shù)。
注意,super 始終應(yīng)是子類(lèi)構(gòu)造函數(shù)的第一條語(yǔ)句。訪(fǎng)問(wèn)Java超級(jí)關(guān)鍵字以了解更多信息。
抽象是面向?qū)ο缶幊痰闹匾拍?。抽象僅顯示所需的信息,所有不必要的細(xì)節(jié)都保持隱藏。這使我們能夠通過(guò)使用更簡(jiǎn)單,更高級(jí)的想法省略或隱藏細(xì)節(jié)來(lái)管理復(fù)雜性。
抽象的實(shí)際示例可以是摩托車(chē)制動(dòng)器。我們知道剎車(chē)的作用。當(dāng)我們踩剎車(chē)時(shí),摩托車(chē)將停止。但是,制動(dòng)器的工作對(duì)我們而言是隱藏的。
隱藏制動(dòng)器工作原理的主要優(yōu)點(diǎn)是,現(xiàn)在制造商可以為不同的摩托車(chē)使用不同的制動(dòng)器,但是制動(dòng)器的作用是相同的。
讓我們舉一個(gè)實(shí)例來(lái)幫助我們更好地理解Java抽象。
abstract class Animal { abstract void makeSound(); } class Dog extends Animal { public void makeSound() { System.out.println("Bark bark."); } } class Cat extends Animal { public void makeSound() { System.out.println("Meows "); } } class Main { public static void main(String[] args) { Dog d1 = new Dog(); d1.makeSound(); Cat c1 = new Cat(); c1.makeSound(); } }
輸出:
Bark bark Meows
在上面的示例中,我們創(chuàng)建了一個(gè)超類(lèi)Animal。超類(lèi)Animal具有抽象方法makeSound()。
makeSound()方法無(wú)法在Animal內(nèi)部實(shí)現(xiàn)。這是因?yàn)槊糠N動(dòng)物都會(huì)發(fā)出不同的聲音。因此,Animal的所有子類(lèi)都有不同的makeSound()實(shí)現(xiàn)方法。
我們不能以對(duì)Animal的所有子類(lèi)都正確的方式在Animal中實(shí)現(xiàn)makeSound()。 因此,Animal中makeSound()的實(shí)現(xiàn)保持隱藏狀態(tài)。
在上面的示例中,Dog實(shí)現(xiàn)了它自己的makeSound()實(shí)現(xiàn),Cat實(shí)現(xiàn)了自己的makeSound()。
我們使用abstract關(guān)鍵字來(lái)創(chuàng)建抽象類(lèi)和方法。
抽象方法沒(méi)有任何實(shí)現(xiàn)(方法體)。
包含抽象方法的類(lèi)也應(yīng)該是抽象的。
我們不能創(chuàng)建抽象類(lèi)的對(duì)象。
為了實(shí)現(xiàn)抽象類(lèi)的功能,我們從其繼承子類(lèi)并創(chuàng)建該子類(lèi)的對(duì)象。
子類(lèi)必須重寫(xiě)抽象類(lèi)的所有抽象方法。但是,如果子類(lèi)被聲明為抽象的,則不必強(qiáng)制重寫(xiě)抽象方法。
我們可以使用抽象類(lèi)的引用來(lái)訪(fǎng)問(wèn)抽象類(lèi)的靜態(tài)屬性和方法。例如,
Animal.staticMethod();
在Java中,接口類(lèi)似于抽象類(lèi)。但是,接口沒(méi)有任何非抽象方法。在下一個(gè)教程中,我們將學(xué)習(xí)有關(guān)接口的更多信息。