抽象類別是在 Java 中透過「Abstract」關鍵字宣告的類別。抽象類別是物件導向程式設計 (OOP) 的四個原則之一的概念,稱為「繼承」。繼承是指 Java 類別的一種特性,其中一個稱為「子類別」的類別可以繼承該類別的所有屬性。父類通常稱為“超類”。
在Java中,抽象類別是指其他子類別可以繼承的基底超類別。它可以包含抽象方法和非抽象方法。
第 1 步 - 識別類別中具有預設實作或無實作的方法。
步驟 2 - 刪除這些方法的實作。
第 3 步 - 將抽象關鍵字加入類別聲明中。
步驟 4 - 將抽象關鍵字加入步驟 2 中修改的方法宣告。
第 5 步 - 如果類別有任何需要初始化的實例變量,請新增建構函式來初始化它們。
第 6 步 - 更新抽象類別的任何子類別以實作抽象方法或使其本身成為抽象。
讓我們來看看在 Java 中實例化抽象類別的語法 -
// Abstract Class abstract class Shape { public abstract void draw(); }
由於抽象類別是不完整的類,因此無法使用「new」關鍵字直接實例化它們。
具體子類別 - 為了正確實例化一個不明確或不完整的抽象類,可以選擇使用具體子類別。透過從這個父抽象無縫擴展並實現其每個方法要求,使用者可以成功創建和實現這個新實例化的子類,而不會在操作中出現錯誤或不一致。
Lambda 表達式 - 要從抽象類別建立對象,您還有另一個選擇 - 使用為其所有抽象提供實現的 lambda 表達式。然後根據這些簽章將此 lambda 建立指派給相容的函數介面變數。
讓我們看一個範例程式碼片段來了解抽象類別的使用。第一個場景提供了一個帶有非抽象類別的程式碼。
class Shape { public void printName() { System.out.println("I'm a shape"); } public float area() { return 0; } public void printDetails() { this.printName(); System.out.println("... and my area is " + this.area()); } } class Circle extends Shape { private float radius; public Circle(float radius) { this.radius = radius; } public void printName() { System.out.println("I'm a circle"); } public float area() { return (float) (Math.PI * Math.pow(radius, 2)); } } class Rectangle extends Shape { private float length; private float width; public Rectangle(float length, float width) { this.length = length; this.width = width; } public void printName() { System.out.println("I'm a rectangle"); } public float area() { return length * width; } } public class Main { public static void main(String[] args) { Shape[] shapes = { new Circle(3.5f), new Rectangle(4.0f, 5.0f) }; for (Shape shape : shapes) { shape.printDetails(); } } }
I'm a circle ... and my area is 38.48451 I'm a rectangle ... and my area is 20.0
Circle 和 Rectangle 類別都從「Shape」超類別繼承了 printName()、area() 和 printDetails() 方法。然而,這兩個類別都沒有重寫area()方法來提供自己的實作。
透過呼叫 Circle 物件的 printDetails() 方法,輸出將是「我是一個圓...並且我的面積是 38.48451」。同樣,在 Rectangle 物件上呼叫 printDetails() 方法將輸出「我是一個矩形...並且我的面積是 20.0」。這確保了輸出根據每個類別中提供的具體實現反映正確的形狀及其相應的區域
// With abstract class abstract class Shape { public abstract void printName(); public abstract float area(); public void printDetails() { this.printName(); System.out.println("... and my area is " + this.area()); } } // Concrete class class Circle extends Shape { private float radius; public Circle(float radius) { this.radius = radius; } public void printName() { System.out.print("I'm a circle"); } public float area() { return (float) (Math.PI * Math.pow(radius, 2)); } } // Concrete class class Rectangle extends Shape { private float length; private float width; public Rectangle(float length, float width) { this.length = length; this.width = width; } public void printName() { System.out.print("I'm a rectangle"); } public float area() { return length * width; } } // Main class public class Main { public static void main(String[] args) { Shape[] shapes = { new Circle(10), new Rectangle(5, 10) }; for (Shape shape : shapes) { shape.printDetails(); } } }
I'm a circle... and my area is 314.15927 I'm a rectangle... and my area is 50.0
在上面更新的程式碼中,Circle 和 Rectangle 類別實作了「Shape」抽象類別中定義的抽象方法 printName() 和 area()。 Shape 類別中的 printDetails() 方法可以使用這些方法列印出形狀名稱及其各自的區域。
透過將 Shape 設為抽象類別並定義抽象方法,我們確保任何擴展 Shape 類別的類別都必須為 printName() 和 area() 方法提供自己的實作。
interface Nameable { String getName(); } abstract class Shape { private Nameable nameable; public Shape(Nameable nameable) { this.nameable = nameable; } public abstract float area(); public void printDetails() { System.out.println("I'm a " + nameable.getName() + " ... and my area is " + this.area()); } } class Circle extends Shape { private float radius; public Circle(float radius) { super(() -> "circle"); this.radius = radius; } @Override public float area() { return (float) (Math.PI * Math.pow(radius, 2)); } } class Rectangle extends Shape { private float width; private float height; public Rectangle(float width, float height) { super(() -> "rectangle"); this.width = width; this.height = height; } @Override public float area() { return width * height; } } public class Main { public static void main(String[] args) { Shape[] shapes = { new Circle(10), new Rectangle(5, 10) }; for (Shape shape : shapes) { shape.printDetails(); } } }
I'm a circle ... and my area is 314.15927 I'm a rectangle ... and my area is 50.0
在此程式碼的最新更新中,我們引入了一種改進的方法,將 Shape 指定為抽象類,同時將其 getName() 函數內部化。進一步的改進涉及整合 printName 方法,該方法成功地利用 getName() 的資料來顯示每個對應形狀的名稱。對於 Circle 和 Rectangle 子類別 - 它們現在使用 lambda 表達式重寫對應的 getName,以便準確識別預期的形式。
總而言之,抽象類別只能透過其基底子類別實例化,而不能直接實例化。這是一個繼承的概念。
這背後的主要原因是抽象類別並不是其方法和物件的完整實現,而是被子類別用來繼承它們。
以上是如何在Java中實例化一個抽象類別?的詳細內容。更多資訊請關注PHP中文網其他相關文章!