Java 教程

Java 控制語句

面向物件程式設計

Java 內建類

Java 檔案處理

Java 錯誤和異常

Java 多執行緒

Java 同步

Java 網路程式設計

Java 集合

Java 介面

Java 資料結構

Java 集合演算法

高階 Java

Java 雜項

Java API 和框架

Java 類引用

Java 有用資源

Java - 訪問修飾符



Java **訪問修飾符** 用於指定變數的作用域資料成員、方法、類或建構函式。這些有助於限制和保護資料的訪問(或訪問級別)。

Java中有四種不同的訪問修飾符,我們列舉如下:

  • 預設(不需要關鍵字)
  • 私有 (private)
  • 受保護 (protected)
  • 公有 (public)
java access modifiers

預設訪問修飾符

預設訪問修飾符意味著我們沒有顯式宣告類、欄位、方法等的訪問修飾符。

未宣告任何訪問控制修飾符的變數或方法可用於同一包中的任何其他類。介面中的欄位隱式為 public static final,介面中的方法預設為 public。

預設訪問修飾符示例

變數和方法可以宣告為沒有任何修飾符,如下例所示:

String version = "1.5.1";

boolean processOrder() {
   return true;
}

私有訪問修飾符

宣告為私有的方法、變數和建構函式只能在其宣告的類中訪問。

私有訪問修飾符是最嚴格的訪問級別。類和介面不能是私有的。

如果類中存在公共 getter 方法,則可以訪問宣告為私有的變數。

使用 private 修飾符是物件封裝自身並隱藏外部世界資料的主要方式。

私有訪問修飾符示例

示例 1

以下類使用私有訪問控制:

public class Logger {
   private String format;

   public String getFormat() {
      return this.format;
   }

   public void setFormat(String format) {
      this.format = format;
   }
}

這裡,Logger 類的 *format* 變數是私有的,因此其他無法直接檢索或設定其值。

因此,為了使此變數可用於外部世界,我們定義了兩個公共方法:*getFormat()*,它返回 format 的值,以及 *setFormat(String)*,它設定其值。

示例 2

在此示例中,Logger 類的類資料成員和方法是私有的。我們嘗試在另一個類 Main 中訪問這些類方法。

class Logger {
  private String format;

  private String getFormat() {
    return this.format;
  }

  private void setFormat(String format) {
    this.format = format;
  }
}

public class Main {
  public static void main(String[] args) {
    // Creating an object 
    Logger log = new Logger();
    // Setting the value
    log.setFormat("Text");
    // Getting the value
    System.out.println(log.getFormat());

  }
}

輸出

Main.java:18: error: setFormat(String) has private access in Logger
    log.setFormat("Text");
       ^
Main.java:20: error: getFormat() has private access in Logger
    System.out.println(log.getFormat());
                          ^
2 errors

受保護訪問修飾符

在超類中宣告為受保護的變數、方法和建構函式只能被其他包中的子類或受保護成員類的包中的任何類訪問。

受保護訪問修飾符不能應用於類和介面。方法、欄位可以宣告為受保護的,但是介面中的方法和欄位不能宣告為受保護的。

受保護訪問使子類有機會使用幫助程式方法或變數,同時阻止不相關的類嘗試使用它。

受保護訪問修飾符示例

示例 1

以下父類使用受保護的訪問控制,以允許其子類重寫 *openSpeaker()* 方法:

class AudioPlayer {
   protected boolean openSpeaker(Speaker sp) {
      // implementation details
   }
}

class StreamingAudioPlayer extends AudioPlayer {
   boolean openSpeaker(Speaker sp) {
      // implementation details
   }
}

這裡,如果我們將 `openSpeaker()` 方法定義為私有(private),那麼除了 `AudioPlayer` 類之外,任何其他類都無法訪問它。如果將其定義為公共(public),那麼外部世界的所有類都可以訪問它。但我們的意圖是僅將其暴露給它的子類,這就是我們使用受保護(protected)修飾符的原因。

示例 1

此示例演示了受保護訪問修飾符的使用。

// Class One
class One {
  protected void printOne() {
    System.out.println("printOne method of One class.");
  }
}

// Inheriting class One on Main
public class Main extends One {
  public static void main(String[] args) {
    // Creating an object of Main class
    Main obj = new Main();

    // Calling printOne() method of class One
    // through the object of Main class
    obj.printOne();
  }
}

輸出

printOne method of One class.

公共訪問修飾符

宣告為公共(public)的類、方法、建構函式、介面等可以從任何其他類訪問。因此,在公共類內宣告的欄位、方法、程式碼塊可以從屬於 Java 宇宙的任何類訪問。

但是,如果我們嘗試訪問的公共類位於不同的包中,那麼仍然需要匯入該公共類。由於類的繼承性,類的所有公共方法和變數都將被其子類繼承。

語法

以下函式使用公共訪問控制:

public static void main(String[] arguments) {
   // ...
}

應用程式的 `main()` 方法必須是公共的。否則,Java 直譯器(例如 java)將無法呼叫它來執行該類。

公共訪問修飾符示例

此示例演示了公共訪問修飾符的使用。

// Class One
class One {
  public void printOne() {
    System.out.println("printOne method of One class.");
  }
}

public class Main {
  public static void main(String[] args) {
    // Creating an object of class One
    One obj = new One();

    // Calling printOne() method of class One
    obj.printOne();
  }
}

輸出

This example demonstrates the use of public access modifier.

訪問修飾符和繼承

繼承方法將強制執行以下規則:

  • 在超類中宣告為公共的方法在所有子類中也必須是公共的。

  • 在超類中宣告為受保護的方法在子類中必須是受保護的或公共的;它們不能是私有的。

  • 私有方法根本不會被繼承,因此沒有關於它們的規則。

下表根據訪問修飾符總結了在相同/不同類(或包)中的可訪問性。

java access modifiers - summary

帶有繼承的訪問修飾符示例

在這個示例中,我們建立了一個類,其中包含一個私有變數 `age` 和一個具有預設作用域的變數 `name`。使用 setter/getter 方法,我們更新 `age` 並獲取其值,而 `name` 是直接更新的。

public class Puppy {
   private int age;
   String name;

   public Puppy() {      
   }

   public void setAge( int age ) {
      this.age = age;
   }

   public int getAge( ) {
      return age;
   }

   public static void main(String []args) {
      Puppy myPuppy = new Puppy();

      // update age variable using method call
      myPuppy.setAge( 2 );

      // update name directly
      myPuppy.name = "Tommy";
      System.out.println("Age: " + myPuppy.getAge() +", name: " + myPuppy.name );
   }
}

輸出

Age: 2, name: Tommy
java_modifier_types.htm
廣告