深入理解 Java 修飾符與封裝:訪問許可權、行為控制與資料隱藏

發表於2024-03-05

Java 修飾符

Java 修飾符 用於控制類、屬性、方法和建構函式的訪問許可權和行為。它們可以分為兩組:

  1. 訪問修飾符:
  • public: 意味著程式碼對所有類可訪問。
  • private: 意味著程式碼只能在宣告的類內部訪問。
  • default: 意味著程式碼只能在同一包中訪問。
  • protected: 意味著程式碼在同一包和子類中可訪問。
  1. 非訪問修飾符:
  • final: 意味著類不能被繼承,屬性和方法不能被重寫。
  • static: 意味著屬性和方法屬於類,而不屬於物件。
  • abstract: 意味著類不能用於建立物件,方法沒有主體,必須由子類提供。
  • transient: 意味著在序列化包含它們的物件時,屬性和方法將被跳過。
  • synchronized: 意味著方法一次只能由一個執行緒訪問。
  • volatile: 意味著屬性的值不會在本地執行緒快取,總是從“主記憶體”讀取。

示例:

訪問修飾符:

// public類可以被任何類訪問
public class Main {

  // private屬性只能在 Main 類內部訪問
  private int x = 10;

  // default方法只能在同一個包中訪問
  void myMethod() {
    System.out.println("This is a default method.");
  }

  // protected方法可以在同一個包和子類中訪問
  protected void myProtectedMethod() {
    System.out.println("This is a protected method.");
  }

  public static void main(String[] args) {
    Main myObj = new Main();
    System.out.println(myObj.x); // 錯誤,無法訪問私有屬性
    myObj.myMethod(); // 可以訪問 default 方法
    myObj.myProtectedMethod(); // 可以訪問 protected 方法
  }
}

非訪問修飾符:

public class Main {

  // final屬性不能被修改
  final int y = 20;

  // static方法可以在不建立物件的情況下訪問
  static void myStaticMethod() {
    System.out.println("This is a static method.");
  }

  // abstract方法沒有主體,必須由子類提供
  abstract void myAbstractMethod();

  public static void main(String[] args) {
    // y = 30; // 錯誤,無法修改 final 屬性
    myStaticMethod(); // 可以訪問 static 方法
    // myAbstractMethod(); // 錯誤,無法直接呼叫抽象方法
  }
}

// 子類繼承 Main 類並提供抽象方法的主體
class Child extends Main {

  @Override
  void myAbstractMethod() {
    System.out.println("This is the implementation of myAbstractMethod.");
  }
}

一些額外的說明:

  • 可以使用多個修飾符來修飾類、屬性、方法和建構函式。例如,public final 表示類是公開的並且不能被繼承。
  • 修飾符是 Java 語言的重要組成部分,它們可以幫助您控制程式碼的訪問許可權和行為。

以下是一些有關 Java 修飾符的其他重要資訊:

  • default 修飾符 也可以稱為 package-private 修飾符。
  • protected 修飾符允許子類訪問父類中的成員,但不允許外部類訪問。
  • static 變數和方法也稱為 類變數 和 類方法。
  • abstract 類不能被例項化,只能被繼承。
  • transient 變數不會被序列化。
  • synchronized 方法可以防止多個執行緒同時執行。
  • volatile 變數保證每次讀取都將獲取最新的值。

Java 封裝

封裝 的含義是確保敏感資料對使用者隱藏。為了實現這一點,你需要:

  1. 將類變數/屬性宣告為私有
  2. 提供公共的 get 和 set 方法以訪問和更新私有變數的值

Get 和 Set 方法

私有變數只能在同一類中訪問(外部類無法訪問)。但是,如果我們提供了公共的 get 和 set 方法,就可以訪問它們。

get 方法 返回變數值,而 set 方法 設定值。

兩者的語法是它們都以 get 或 set 開頭,後面跟著變數的名稱,首字母大寫:

public class Person {
  private String name; // private = 受限制的訪問

  // Getter
  public String getName() {
    return name;
  }

  // Setter
  public void setName(String newName) {
    this.name = newName;
  }
}

示例解釋

  • get 方法返回變數 name 的值。
  • set 方法接受一個引數(newName)並將其分配給 name 變數。關鍵字 this 用於引用當前物件。

然而,由於 name 變數被宣告為私有,我們無法從此類外部訪問它:

public class Main {
  public static void main(String[] args) {
    Person myObj = new Person();
    myObj.name = "John"; // 錯誤
    System.out.println(myObj.name); // 錯誤
  }
}

如果變數被宣告為 public,我們期望以下輸出:

John

然而,由於我們嘗試訪問一個私有變數,我們得到一個錯誤:

MyClass.java:4: error: name has private access in Person
  myObj.name = "John";
    ^
MyClass.java

:5: error: name has private access in Person
    System.out.println(myObj.name);
        ^
2 errors

相反,我們使用 getName() 和 setName() 方法來訪問和更新變數:

public class Main {
  public static void main(String[] args) {
    Person myObj = new Person();
    myObj.setName("John"); // 將 name 變數的值設定為 "John"
    System.out.println(myObj.getName());
  }
}

// 輸出 "John"

為什麼封裝?

  • 更好地控制類的屬性和方法
  • 類屬性可以被設定為只讀(如果僅使用 get 方法)或只寫(如果僅使用 set 方法)
  • 靈活性:程式設計師可以更改程式碼的一部分而不影響其他部分
  • 資料的安全性增加

封裝的優點:

  • 提高安全性:隱藏內部實現細節,防止意外修改或訪問敏感資料。
  • 提高程式碼的模組化:將程式碼組織成獨立的模組,每個模組只暴露必要的介面。
  • 提高程式碼的可重用性:封裝的模組可以被其他程式碼重用,降低程式碼的重複性。
  • 提高程式碼的維護性:易於理解和維護程式碼,降低程式碼的複雜度。

一些額外的說明:

  • 可以使用多個修飾符來修飾 get 和 set 方法,例如 public、protected 和 private。
  • 可以使用 final 修飾符來宣告常量,常量不能被修改。
  • 可以使用 static 修飾符來宣告靜態方法和變數,靜態方法和變數屬於類,而不是物件。

最後

為了方便其他裝置和平臺的小夥伴觀看往期文章:

微信公眾號搜尋:Let us Coding,關注後即可獲取最新文章推送

看完如果覺得有幫助,歡迎 點贊、收藏、關注

相關文章