Java 中 final 和 abstract 的區別


在使用 Java 時,理解 final 和 abstract 的概念對於編寫高效且易於維護的程式碼至關重要。雖然 final 和 abstract 在面向物件程式設計中都扮演著重要的角色,但它們具有不同的用途。在本文中,我們將探討 final 和 abstract 關鍵字在 Java 中的語法和用法,以及它們的不同實現方式。

語法

要定義一個 final 類或方法,我們在類或方法宣告之前使用關鍵字“final”。例如,一個 final 類將定義如下:

final class MyClass {
   // Class implementation
}

要定義一個 abstract 類或方法,我們在類或方法宣告之前使用關鍵字“abstract”。例如,一個 abstract 類將定義如下:

abstract class MyAbstractClass {
   // Class implementation
}

語法解釋

關鍵字 "final" 用於指示一個類、方法或變數不能被修改或重寫。final 類不能被子類化,final 方法不能在任何子類中被重寫。此外,final 變數一旦賦值就不能重新賦值。

另一方面,關鍵字 "abstract" 用於指示一個類或方法是不完整的,必須由另一個類擴充套件或實現。abstract 類不能直接例項化,並且它可能包含 abstract 方法,這些方法必須由其子類實現。

方法 1:Final

在這種方法中,我們將重點關注 final 關鍵字的用法。使用 final 的主要目的是在 Java 中建立不可變實體。不可變物件是指其狀態一旦建立就不能更改的物件。

演算法

  • 將類或方法宣告為 final。

  • 在類或方法中實現所需的功能。

  • 防止其他類或子類進行任何進一步的修改。

示例

final class ImmutableClass {
   private final String name;

   public ImmutableClass(String name) {
      this.name = name;
   }

   public String getName() {
      return name;
   }
}

public class Main {
   public static void main(String[] args) {
      ImmutableClass immutableObject = new ImmutableClass("Hello");
      System.out.println(immutableObject.getName());
   }
}

輸出

Hello

方法 1 中程式碼的解釋

ImmutableClass 被宣告為不可變且不可擴充套件的,因為在宣告期間包含了“final”關鍵字。它包含一個名為“name”的單個私有例項變數,該變數也被標記為 final,以防止在建構函式中初始賦值後進行修改。

ImmutableClass 的建構函式接受一個名為 name 的 String 引數,並將它的值賦給 name 變數。這確保了 name 變數只能在物件建立期間設定一次,並且之後不能修改。

在 ImmutableClass 中,有一個公共方法 getName() 用於獲取物件的名稱。由於 name 元素被宣告為私有,因此必須阻止外部訪問它,因此需要實現此查詢工具。我們的程式入口點從 Main 類的 main() 函式開始,我們用引數“Hello”例項化一個 ImmutableClass 物件。

初始化後,我們將新例項儲存在記憶體節省變數 immutableObject 中。我們透過將 System.out.println() 的輸出流設定為 immutableObject 的 getName() 方法的返回值來結束我們的 main 函式,以便我們的程式透過在螢幕上顯示“Hello”(我們最初指定的名稱)來顯示成功的執行。

方法 2:Abstract

在這種方法中,我們將重點關注 abstract 關鍵字的用法。abstract 類用於提供公共介面併為一組相關類定義公共行為。

演算法

  • 將類宣告為 abstract。

  • 定義 abstract 方法,這些方法應該由子類實現。

  • 在 abstract 類中實現公共功能。

示例

abstract class Shape {
   protected String color;

   public Shape(String color) {
      this.color = color;
   }

   abstract double getArea();
}

class Circle extends Shape {
   private double radius;

   public Circle(String color, double radius) {
      super(color);
      this.radius = radius;
   }

   @Override
   double getArea() {
      return Math.PI * radius * radius;
   }
}

public class Main {
   public static void main(String[] args) {
      Circle circle = new Circle("Red", 2.5);
      System.out.println("Color: " + circle.color);
      System.out.println("Area: " + circle.getArea());
        
   }
}

輸出

Color: Red
Area: 19.634954084936208

Shape 類使用 abstract 關鍵字宣告為 abstract 類。abstract 類不能被例項化,這意味著不能直接建立 Shape 類的物件。Shape 類有一個名為 color 的受保護例項變數和一個接受 color 引數並將其值賦給 color 變數的建構函式。

Shape 類還聲明瞭一個名為 getArea() 的 abstract 方法。在程式設計過程中,abstract 方法在建立程式碼實現的框架和結構方面發揮著關鍵作用。具體來說,使用此工具集,開發人員可以建立方法和結構,而無需立即在執行時確定它們,而是將它們留待以後從具體子類(即引入類別之外的類)進一步開發。

讓我們具體研究 getArea() 在這裡是如何相關的:簡而言之,計算面積取決於形狀分類和各種開發者使用的子型別因素;因此,將此變化因素放入非立即或獨立開發中,允許任何具體子類實現自定義,而無需擔心在子級建立之前表達的整體結構中斷或完整性維護問題。此外,關於我們在這裡的基礎工作,Shape 可以被視為由 Circle 擴充套件為這樣的子類,並進一步進行調製以整合到具有類似模板方法的開發的其他結構中。它添加了一個名為 radius 的私有例項變數,並帶有一個同時接受 color 和 radius 引數的建構函式。Circle 的建構函式使用 super 關鍵字呼叫其超類 (Shape) 的建構函式來初始化 color 變數。然後它將 radius 引數賦給 Circle 類的 radius 變數。

Circle 類重寫了從 Shape 類繼承的 getArea() 方法。在這種情況下,它使用公式:π * radius * radius 計算圓的面積。Math.PI 常量表示 π 的值(約為 3.14159)。

此程式設計序列的基礎是 Main 類,在其中我們可以找到 main 方法 - 建立程式的起點。在這個方法中,我們啟動一個 Circle 物件,最初半徑為 2.5,顏色為“紅色”。此新物件從其各自的兩個建構函式中獲取資訊:首先呼叫 Circle 建構函式,然後在重置其顏色值時呼叫 Shape 建構函式的幫助。最後,我們將“circle”指定為此特定例項的變數名。

最後,使用 circle.color 訪問 circle 物件的 color 變數並將其列印到控制檯。還對 circle 物件呼叫 getArea() 方法,並將返回值也列印到控制檯。

Java 中 final 和 abstract 的區別

區別

方法 1:Final

方法 2:Abstract

例項化

允許例項化類

不能直接例項化

繼承

不能被子類化

允許子類化

方法重寫

方法不能被重寫

abstract 方法必須由子類實現

可修改性

防止修改類、方法或變數

為在子類中修改和擴充套件提供藍圖

用法

用於建立不可變實體或強制執行特定行為

用於為相關類定義公共介面和行為

結論

總之,雖然 final 和 abstract 具有不同的用途,但它們都是 Java 程式設計中的重要工具。透過適當使用它們,您可以編寫更健壯、更靈活、更易於維護的程式碼,這些程式碼符合設計原則並滿足特定需求。無論是建立不可變實體還是建立公共介面,final 和 abstract 關鍵字都有助於開發高質量的 Java 應用程式。

更新於:2023年7月28日

2K+ 次瀏覽

啟動您的 職業生涯

完成課程獲得認證

開始學習
廣告
© . All rights reserved.