首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 綜合教學

Java 套件與存取權限進階實戰:Father、Son 類別跨套件存取控制

     編輯:Java 綜合教學

專案結構與需求

  • pack1 套件:Father(父類)、Son(子類,非繼承關係)
  • pack2 套件:Text_F(測試主類)
  • 驗證 private、protected、public、default 四種存取層級在同套件與跨套件的可見性

pack1.Father 類別

package pack1;

public class Father {
    private int age;           // 僅本類別可見
    public String name;        // 公開存取
    
    public int getAge() { return age; }
    public void setAge(int age) { this.age = age; }
    
    public void work() { 
        System.out.println(name + ": I have a job."); 
    }
    
    public void drive() { 
        System.out.println(name + ": I have a car, I'm driving."); 
    }
}

pack1.Son 類別

package pack1;

public class Son {
    protected int age;         // 同套件 + 子類可見(雖此處非繼承 Father)
    private String name;       // 僅本類別可見
    
    public void setAge(int age) { this.age = age; }
    public int getAge() { return age; }
    
    public void setName(String name) { this.name = name; }
    public String getName() { return name; }
    
    private int play() {       // 僅本類別可見
        System.out.println(name + ": I like to play !");
        return age;
    }
    
    public int getPlay() { return age; } // 公開存取器
    
    public void study() { 
        System.out.println(name + ": I like to study !"); 
    }
}

pack2.Text_F 測試類別

package pack2;

import pack1.Father;
import pack1.Son;

public class Text_F {
    public static void main(String[] args) {
        // 測試 Father
        Father f1 = new Father();
        f1.setAge(55);           // OK: public setter
        f1.name = "張三";         // OK: public field
        
        f1.drive();              // OK: public method
        f1.work();               // OK: public method
        System.out.println(f1.name + "的年齡:" + f1.getAge() + "歲。");
        
        // 測試 Son
        Son s1 = new Son();
        s1.setAge(17);           // OK: public setter
        s1.setName("張三三");     // OK: public setter
        s1.study();              // OK: public method
        System.out.println(s1.getName() + "的年齡:" + s1.getAge() + "歲。");
        
        // 編譯錯誤示範(已註解):
        // f1.age = 10;        // 錯誤: private
        // s1.age = 20;        // 錯誤: protected (跨套件非子類不可見)
        // s1.name = "test";   // 錯誤: private
        // s1.play();          // 錯誤: private
    }
}

執行結果

程式執行結果截圖

存取權限矩陣總結

修飾符同類別同套件不同套件子類不同套件非子類
private✓✗✗✗
default (無)✓✓✗✗
protected✓✓✓✗
public✓✓✓✓

關鍵觀察點

  1. Father.age 為 private,必須透過 getAge()/setAge() 存取
  2. Son.age 為 protected,在 pack2 中不可直接存取(非子類),需透過公開方法
  3. Son.name 為 private,同樣需透過 getName()/setName()
  4. Son.play() 為 private,外部完全不可見,連 getPlay() 也只是回傳 age 而非呼叫 play()
  5. 跨套件測試類只能使用 public 成員,完美驗證了封裝邊界

設計建議

  • 欄位優先 private,提供 public 存取器(Getter/Setter)
  • protected 僅用於「預期被子類繼承且需直接存取」的場景
  • 避免使用 default(包私有)除非刻意限制在模組內部
  • 公開 API 應盡量縮小可見範圍,遵循「最小權限原則」
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved