JavaRush /Java Blog /Random-TW /Java 中的抽象類別和具體範例

Java 中的抽象類別和具體範例

在 Random-TW 群組發布
你好!在之前的講座中,我們熟悉了介面並弄清楚了它們的用途。今天的主題與上一個主題有一些共同點。我們來談談Java中的抽象類別Java 中的抽象類別和具體範例 - 1

為什麼類別被稱為“抽象類別”

你可能還記得「抽象」是什麼——我們已經介紹過了:)如果你突然忘記了,沒關係,我們記住:這是OOP 的原則,根據這個原則,在設計類別和創建物件時,需要突出顯示僅保留實體的主要屬性並丟棄次要屬性。例如,如果我們正在設計一個班級SchoolTeacher(學校老師),我們不太可能需要「身高」特徵。確實:對一名教師來說,這個特質並不重要。但如果我們在程序中創建一個類別BasketballPlayer- 籃球運動員 -身高將成為主要特徵之一。因此,抽象類別是一組未來類別中最抽象、最近似的「空白」。這種製劑不能以成品形式使用—它太「生」了。但它描述了未來類別(抽象類別的繼承者)將具有的某種一般狀態和行為。

Java 抽象類別範例

讓我們來看一個關於汽車的簡單例子:
public abstract class Car {

   private String model;
   private String color;
   private int maxSpeed;

   public abstract void gas();

   public abstract void brake();

   public String getModel() {
       return model;
   }

   public void setModel(String model) {
       this.model = model;
   }

   public String getColor() {
       return color;
   }

   public void setColor(String color) {
       this.color = color;
   }

   public int getMaxSpeed() {
       return maxSpeed;
   }

   public void setMaxSpeed(int maxSpeed) {
       this.maxSpeed = maxSpeed;
   }
}
這就是最簡單的抽象類別的樣子。正如你所看到的,沒什麼特別的:)我們需要它做什麼?首先,他用最抽象的方式描述了我們需要的實體──汽車。摘要這個字出現在這裡是有原因的。世界上不存在「公正的機器」。有卡車、賽車、轎車、轎跑車、SUV。 我們的抽象類別只是一個“藍圖”,稍後我們將根據它建立汽車類別。
public class Sedan extends Car {

   @Override
   public void gas() {
       System.out.println("The sedan accelerates!");
   }

   @Override
   public void brake() {
       System.out.println("The sedan slows down!");
   }

}
這很像我們在繼承講座中談到的內容。只有在那裡我們有一個類別Car及其方法不是抽象的。但這個解決方案有許多缺點,這些缺點在抽象類別中都得到了修正。首先也是最重要的,不能建立抽象類別的實例:
public class Main {

   public static void main(String[] args) {

       Car car = new Car(); // Error! The Car class is abstract!
   }
}
這個「技巧」是由 Java 的創建者專門實現的。再次記住:抽象類別只是未來「普通」類別的藍圖。您不需要圖紙的副本,對嗎?所以不需要建立抽象類別的實例:)如果該類別Car不是抽象的,我們可以輕鬆創建它的物件:
public class Car {

   private String model;
   private String color;
   private int maxSpeed;

   public void gas() {
       // some logic
   }

   public  void brake() {
       // some logic
   }
}


public class Main {

   public static void main(String[] args) {

       Car car = new Car(); // Everything is OK, the machine has been created
   }
}
現在我們的程式中有某種奇怪的汽車 - 不是卡車,不是賽車,不是轎車,而是一般的東西。自然界中不存在同樣的「只是一台機器」。同樣的例子也適用於動物。想像一下,如果物件出現在你的程式中Animal——「只是一隻動物」。它是什麼類型,屬於什麼科,有什麼特徵──目前還不清楚。在節目中看到他會很奇怪。自然界中不存在「只有動物」。只有狗、貓、狐狸、鼴鼠和其他動物。抽象類別將我們從「只是物件」中解放出來。它們給我們一個基本的狀態和行為。例如,所有汽車都必須有型號顏色最高速度,並且還必須能夠加油煞車。就這樣。這是一個通用的抽象方案,然後你自己設計你需要的類別。 請注意:抽象類別中的兩個方法也被指定為abstract,而且它們根本沒有實作。原因是相同的:抽象類別不會為“純粹的機器”創建“預設行為”。他們只是說他們應該能夠製造所有的汽車。但是,如果您仍然需要預設行為,則可以在抽象類別中實作方法。Java 並不禁止這樣做:
public abstract class Car {

   private String model;
   private String color;
   private int maxSpeed;

   public void gas() {
       System.out.println("Let's go!");
   }

   public abstract void brake();

   //getters and setters
}


public class Sedan extends Car {

   @Override
   public void brake() {
       System.out.println("The sedan slows down!");
   }

}

public class Main {

   public static void main(String[] args) {

       Sedan sedan = new Sedan();
       sedan.gas();
   }
}
控制台輸出: “加速!” 正如您所看到的,我們在抽象類別中實作了一個方法,但沒有實作第二個方法。這樣一來,我們類別的行為Sedan就被分成了兩部分:如果你呼叫它上面的方法gas(),它就會從父抽象類別中「拉起」Car,而brake()我們在類別中重新定義了該方法Sedan。事實證明它非常方便和靈活。但現在我們的類別不那麼抽象了嗎?畢竟,事實上他的方法已經實現了一半了。事實上──這是一個非常重要的特性──如果一個類別至少有一個方法是抽象的,那麼該類別就是抽象的。至少兩種方法中的一種,至少一千種方法中的一種——這並不重要。我們甚至可以實作所有的方法,而不留下任何抽象的方法。會有一個沒有抽象方法的抽象類別。原則上,這是可能的,編譯器不會產生錯誤,但最好不要這樣做:抽象這個詞將失去其意義,你的程式設計師同事看到這一點會感到非常驚訝:/此外,如果一個方法標有“abstract”一詞,每個後代類別都必須實現或聲明為“abstract”。否則編譯器會拋出錯誤。當然,每個類別只能繼承一個抽象類,因此在繼承方面,抽象類別和普通類別沒有區別。不管我們是從抽象類別繼承還是從常規類別繼承,都只能有一個父類別。

為什麼Java中沒有多重類別繼承?

我們已經說過Java中沒有多重繼承,但我們還沒有真正弄清楚為什麼。現在讓我們試試看。關鍵是,如果 Java 具有多重繼承,子類別將無法決定選擇哪種行為。假設我們有兩個類別 -TosterNuclearBomb
public class Toster {


 public void on() {

       System.out.println("The toaster is on, the toast is getting ready!");
   }

   public void off() {

       System.out.println("The toaster is off!");
   }
}


public class NuclearBomb {

   public void on() {

       System.out.println("Взрыв!");
   }
}
正如您所看到的,兩者都有一個方法on()。如果是烤麵包機,它會開始烤麵包;如果是核彈,它會引起爆炸。哦:/現在想像你決定(我不知道為什麼突然!)在兩者之間創造一些東西。這是你的課 - MysteriousDevice!當然,這段程式碼是行不通的,我們將其簡單地作為「它可能是怎樣的」的一個例子來展示:
public class MysteriousDevice extends Toster, NuclearBomb {

   public static void main(String[] args) {

       MysteriousDevice mysteriousDevice = new MysteriousDevice();
       mysteriousDevice.on(); // And what should happen here? Will we get a toast, or a nuclear apocalypse?
   }
}
讓我們看看我們得到了什麼。這個神秘裝置來自烤麵包機和核彈。兩者都有一個 method on(),因此,不清楚如果我們呼叫它,on()應該在物件上觸發哪個方法。MysteriousDevice對象將無法理解這一點。好吧,錦上添花的是:核彈沒有方法off(),所以如果我們猜錯了,就沒有辦法關閉設備。 Java 中的抽象類別和具體範例 - 2 正是由於這種混亂,當一個物件不清楚它應該選擇哪種行為時,Java 的創建者放棄了多重繼承。但是,您還記得 Java 類別實作了許多介面。順便說一下,你在學習中至少已經接觸過一門抽象類別了!雖然,也許我沒有註意到:)
public abstract class Calendar implements Serializable, Cloneable, Comparable<Calendar>
這是你的老朋友級Calendar。它是抽象的並且有幾個繼承人。其中之一是GregorianCalendar。您已經在有關日期的課程中使用過它了:)一切似乎都清楚了,只剩下一點:抽象類別和介面之間的根本區別是什麼?為什麼他們將兩者都添加到 Java 中,而不是僅限於其中一種?這可能就足夠了。我們將在下一講中討論這個!再見:)
留言
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION