在OOP這個概念中,所有的物件都是透過類別來描述的;但是並不是所有的類別都是用來描述物件的。如果一個類別沒有包含足夠的資訊來描述一個具體的對象,這樣的類別稱為抽象類別。
抽象類別:(1)抽象類別不能實例化對象,如果實例化某個對象,編譯就無法通過。只有抽象類別的非抽象子類別可以建立物件(2)可以包含:成員變數、成員方法、建構方法等。 (3)建構方法、類別方法(用static修飾的方法)不能宣告為抽象方法
抽象方法:(1)如果一個類別包含抽象方法,那麼該類別一定是抽象類別(2)任何子類別必須重寫父類別的抽象方法,或宣告本身為抽象類別
#定義:abstract class 類別名稱
Animal:抽象類別--------getName()、move()、drink()
Reptile、Mammal:繼承抽象類別
吃蛇、老虎、山羊、兔子:分別繼承Reptile或Mammal
fammer:bringWater()、feedWater(Animal animal)---- 負責將水帶到指定的地方,然後動物移動到目的地,喝水
#程式碼如下:
package abstractDemo; /** * @author lpx * @Description TODO * @date 2021-04-07 */ public abstract class Animal { abstract String getName(); abstract void move(String destination); abstract void drink(); } abstract class Reptile extends Animal{ } abstract class Mammal extends Animal{ } class Tiger extends Mammal{ private static String name="tiger"; @Override String getName() { return this.name; } @Override void move(String destination) { System.out.println("tiger move to "+destination+"."); } @Override void drink() { System.out.println("tiger lower it is head and drink"); } } class Goat extends Mammal{ private static String name="goat"; @Override String getName() { return this.name; } @Override void move(String destination) { System.out.println("goat move to "+destination+"."); } @Override void drink() { System.out.println("goat lower it head to drink"); } } class Rabbit extends Mammal{ private static String name="rabbit"; @Override String getName() { return this.name; } @Override void move(String destination) { System.out.println("rabbit move to "+destination+"."); } @Override void drink() { System.out.println("rabbit put out it is tongue and drink"); } } class Snake extends Reptile{ private static String name="snake"; @Override String getName() { return this.name; } @Override void move(String destination) { System.out.println("snake move to "+destination+"."); } @Override void drink() { System.out.println("snake dived into and drink"); } } class Farmer{ public void bringWater(String destination){ System.out.println("Farmer bring water to " + destination + "."); } public void feedWater(Animal a){ // polymorphism this.bringWater("Feeding Room"); a.move("Feeding Room"); a.drink(); } } class Test{ public static void main(String[] args) { Farmer fm=new Farmer(); Snake snake=new Snake(); Goat goat=new Goat(); Tiger tiger=new Tiger(); Rabbit rabbit=new Rabbit(); fm.feedWater(snake); fm.feedWater(goat); fm.feedWater(tiger); fm.feedWater(rabbit); } }
執行結果:
#總結:
如果每種動物不是抽像出drink和move方法的話,就無法實現多態。農夫類別就需要根據參數的不同重載多個feedWater。如果繼續增加動物那麼重載個數就越來越多。為了方便對比理解,我也按照常規思維去寫了一下,代碼如下:
package abstractDemo; /** * @author lpx * @Description TODO * @date 2021-04-07 */ class Tiger1{ private static String name="tiger"; String getName() { return this.name; } void move(String destination) { System.out.println("tiger move to "+destination+"."); } void drink() { System.out.println("tiger lower it is head and drink"); } } class Goat1{ private static String name="goat"; String getName() { return this.name; } void move(String destination) { System.out.println("goat move to "+destination+"."); } void drink() { System.out.println("goat lower it head to drink"); } } class Rabbit1{ private static String name="rabbit"; String getName() { return this.name; } void move(String destination) { System.out.println("rabbit move to "+destination+"."); } void drink() { System.out.println("rabbit put out it is tongue and drink"); } } class Farmer1{ public void bringWater(String destination){ System.out.println("Farmer bring water to " + destination + "."); } public void feedWater(Goat1 goat){ // polymorphism this.bringWater("Feeding Room"); goat.move("Feeding Room"); goat.drink(); } public void feedWater(Tiger1 tiger){ // polymorphism this.bringWater("Feeding Room"); tiger.move("Feeding Room"); tiger.drink(); } public void feedWater(Rabbit1 rabbit1) { this.bringWater("Feeding Room"); rabbit1.move("Feeding Room"); rabbit1.drink(); } } public class Test1{ public static void main(String[] args) { Farmer1 farmer1=new Farmer1(); Tiger1 tiger1=new Tiger1(); Goat1 goat1=new Goat1(); Rabbit1 rabbit1=new Rabbit1(); farmer1.feedWater(tiger1); farmer1.feedWater(goat1); farmer1.feedWater(rabbit1); } }
手敲了這個例子,發現基礎很重要呀,以前學習的不細緻,導致很多地方迷糊不知道為啥那麼寫。
(1)一個.java檔案中可以定義多個class類,但是只有一個可以定義為public,且這個類別名稱必須和檔案名稱相同
(2)抽象類別繼承抽象類,不用覆寫其抽象方法(原因也很簡單呀,本身他就是抽象的不能實作方法體)。而非抽象類別繼承抽象類別必須覆寫抽象方法,非抽象方法非必要。
(3)重寫和重載的區別(高頻面試題 ?)
重載:定義相同的方法名,參數不同。屬於編譯時多態
重寫:子類別重寫父類別的方法@Override。屬於運行時多態
以上是Java抽象定義的範例分析的詳細內容。更多資訊請關注PHP中文網其他相關文章!