Access Modifiers: private, protected, public, default

บทนำ: ทำไมต้อง Access Modifiers?

เมื่อเราเขียน private หรือ public เรากำลัง ควบคุมว่าใครเข้าถึงได้

java// ❓ ทำไมต้องมี access modifiers?

public class StudentBad {
    private String studentID;      // ← private: เข้าถึงยากไป?
    public String name;            // ← public: เข้าถึงง่ายเกินไป?
    protected double gpa;          // ← protected: เมื่อไหร่ใช้?
    int year;                      // ← default: คืออะไร?
}

ปัญหา:

  • ❌ ไม่รู้ private vs public ต่างกันไง
  • ❌ ไม่รู้ protected ใช้กับไหน
  • ❌ ไม่รู้ default ทำไมต้องมี
ยาวไปอยากเลือกอ่าน
  1. บทนำ: ทำไมต้อง Access Modifiers?
  2. Access Modifiers ใน Java
  3. โครงสร้างทั่วไป
  4. 1. private: เข้าถึงได้เฉพาะใน Class นี้
  5. private คืออะไร?
  6. Scope ของ private
  7. ตัวอย่าง: private ใน BankAccount
  8. 2. public: เข้าถึงได้ทุกที่
  9. public คืออะไร?
  10. Scope ของ public
  11. ตัวอย่าง: public ใน Different Packages
  12. 3. default (Package-Private): เข้าถึงได้เฉพาะใน Package เดียวกัน
  13. default คืออะไร?
  14. Scope ของ default
  15. ตัวอย่าง: default vs public
  16. 4. protected: เข้าถึงได้ใน Package เดียวกัน และ Subclass
  17. protected คืออะไร?
  18. Scope ของ protected
  19. ตัวอย่าง: protected กับ Inheritance
  20. ตารางเปรียบเทียบ 4 Access Modifiers
  21. ตารางเข้าถึง
  22. ตัวอักษรเพื่อจำ
  23. ตัวอย่างที่ 1: Student Class ทั้ง 4 Modifiers
  24. วิธีใช้จากที่ต่างๆ
  25. ตัวอย่างที่ 2: Bank Account ด้วย 4 Modifiers
  26. Best Practices: เลือก Modifier ที่ถูก
  27. 1. ทั่วไป: ใช้ private แรก
  28. 2. Attributes: เกือบทั้งหมด private
  29. 3. Methods: อยู่ที่ว่า
  30. 4. Constants: เกือบทั้งหมด public static final
  31. ตัวอย่างที่ 3: Temperature Class ด้วย Modifiers
  32. ตัวอย่างที่ 4: Package Structure
  33. ตัวอย่างที่ 5: นักศึกษาที่ศึกษา OOP
  34. สรุป: 4 Access Modifiers
  35. Guide: เลือก Modifier อย่างไร?

Access Modifiers ใน Java

โครงสร้างทั่วไป

text┌─────────────────────────────────────────┐
│        Same Package?                    │
│        (com.example.*)                  │
│     Yes            No                   │
│      │              │                   │
│      ↓              ↓                   │
│   ┌──────┐      ┌──────┐               │
│   │Same? │      │Subclass?            │
│   │Class?│      │(Inherit)            │
│   └──────┘      └──────┘               │
│    ↙    ↘        ↙    ↘                │
│   Y      N      Y      N               │
│   │      │      │      │               │
│   ↓      ↓      ↓      ↓               │
│                                        │
│ public:   ✓      ✓      ✓      ✓      │
│ protected: ✓      ✓      ✓      ✗      │
│ default:   ✓      ✓      ✗      ✗      │
│ private:   ✓      ✗      ✗      ✗      │
│                                        │
└─────────────────────────────────────────┘

1. private: เข้าถึงได้เฉพาะใน Class นี้

private คืออะไร?

private = “ส่วนตัว” เข้าถึงได้เฉพาะ ตัวเอง

javapublic class Student {
    private String studentID;      // ← private
    private double gpa;            // ← private
    
    // ✓ เข้าถึงได้ที่นี่
    public void displayInfo() {
        System.out.println(studentID);  // ✓ OK
        System.out.println(gpa);        // ✓ OK
    }
}

// ❌ ไม่ได้เข้าถึงจากนอก
Student student = new Student();
System.out.println(student.studentID);  // ❌ ERROR! private
System.out.println(student.gpa);        // ❌ ERROR! private

Scope ของ private

text┌──────────────────────────────────┐
│   Class Student                  │
│  ┌────────────────────────────┐  │
│  │ private String studentID   │  │
│  │ private double gpa         │  │
│  ├────────────────────────────┤  │
│  │ public void study() {      │  │
│  │   gpa += 0.1;    ✓ OK     │  │
│  │ }                          │  │
│  └────────────────────────────┘  │
│                                  │
│ ✗ ไม่ได้เข้าถึงจากนอก           │
└──────────────────────────────────┘

┌──────────────────────────────────┐
│   Other Class                    │
│  Student s = new Student();      │
│  s.studentID = "123";  ❌ ERROR  │
│  s.gpa = 3.75;         ❌ ERROR  │
└──────────────────────────────────┘

ตัวอย่าง: private ใน BankAccount

javapublic class BankAccount {
    private String accountNumber;  // ← private
    private double balance;        // ← private
    
    public void deposit(double amount) {
        // ✓ เข้าถึงได้
        this.balance += amount;
    }
}

// ใช้งาน
BankAccount account = new BankAccount();

// ✓ เข้าถึงผ่าน public method
account.deposit(5000);

// ❌ ไม่ได้เข้าถึง private attributes
// account.balance = -10000;  // ERROR!
// account.accountNumber = "hacked";  // ERROR!

ประโยชน์ของ private:

  • ✓ ข้อมูลสำคัญปลอดภัย
  • ✓ บังคับให้ใช้ getter/setter
  • ✓ Encapsulation ที่ดี

2. public: เข้าถึงได้ทุกที่

public คืออะไร?

public = “สาธารณะ” เข้าถึงได้ ทุกที่

javapublic class Student {
    public String name;            // ← public
    
    public void study() {          // ← public
        System.out.println("Studying...");
    }
}

// เข้าถึงได้จากทุกที่
Student student = new Student();
student.name = "John";             // ✓ OK
student.study();                   // ✓ OK

Scope ของ public

text┌──────────────────────┐
│ Class Student        │
│ (public)             │
│                      │
│ public String name   │ ✓ OK
│ public void study()  │ ✓ OK
└──────────────────────┘
         △
         │
    ┌────┴─────┐
    │          │
┌──────────┐ ┌──────────┐
│Package A │ │Package B │
│          │ │          │
│✓ Use it  │ │✓ Use it  │
└──────────┘ └──────────┘

ตัวอย่าง: public ใน Different Packages

text// File 1: src/com/university/models/Student.java
package com.university.models;

public class Student {
    public String name;            // ← public
    
    public void study() {
        System.out.println("Studying...");
    }
}

// File 2: src/com/school/admin/Main.java
package com.school.admin;

import com.university.models.Student;

public class Main {
    public static void main(String[] args) {
        Student student = new Student();
        
        // ✓ เข้าถึงได้ (คน่ละ package)
        student.name = "John";
        student.study();
    }
}

หมายเหตุ: เข้าถึงได้จาก package อื่นๆ ก็ได้


3. default (Package-Private): เข้าถึงได้เฉพาะใน Package เดียวกัน

default คืออะไร?

default = ไม่มี modifier เข้าถึงได้เฉพาะ ใน package เดียวกัน

java// ไม่มี public, private, protected → default

public class Student {
    String studentID;              // ← default
    
    void study() {                 // ← default
        System.out.println("Studying...");
    }
}

Scope ของ default

text┌─────────────────────────────────┐
│    com.university               │
│                                 │
│  ┌────────────────┐             │
│  │ Class Student  │             │
│  │ (default)      │             │
│  │                │             │
│  │ String studentID │ ✓ OK     │
│  │ void study()   │ ✓ OK     │
│  └────────────────┘             │
│           △                     │
│           │                     │
│  ┌────────────────┐             │
│  │ Class Course   │             │
│  │ (same package) │             │
│  │                │             │
│  │ ✓ เข้าถึงได้  │             │
│  └────────────────┘             │
│                                 │
└─────────────────────────────────┘
         ✗ คน่ะ package ไม่ได้!

┌─────────────────────────────────┐
│    com.school                   │
│                                 │
│  ┌────────────────┐             │
│  │ Class Main     │             │
│  │ (other package)│             │
│  │                │             │
│  │ ❌ ไม่ได้      │             │
│  │    เข้าถึง     │             │
│  └────────────────┘             │
│                                 │
└─────────────────────────────────┘

ตัวอย่าง: default vs public

text// File 1: src/com/university/Student.java
package com.university;

public class Student {
    String studentID;              // ← default
    public String name;            // ← public
}

// File 2: src/com/university/Course.java
package com.university;              // ← Same package!

public class Course {
    public static void main(String[] args) {
        Student student = new Student();
        
        // ✓ Same package → เข้าถึงได้
        student.studentID = "6501001";  // ✓ OK (default)
        student.name = "John";          // ✓ OK (public)
    }
}

// File 3: src/com/school/Main.java
package com.school;                 // ← Different package!

import com.university.Student;

public class Main {
    public static void main(String[] args) {
        Student student = new Student();
        
        // ❌ Different package → ไม่ได้เข้าถึง default
        // student.studentID = "6501001";  // ❌ ERROR!
        
        // ✓ public ยังเข้าถึงได้
        student.name = "John";              // ✓ OK
    }
}

4. protected: เข้าถึงได้ใน Package เดียวกัน และ Subclass

protected คืออะไร?

protected = “คุ้มครอง” เข้าถึงได้:

  1. ใน package เดียวกัน ✓
  2. ใน subclass (แม้ต่างแพคเกจ) ✓
javapublic class Person {
    protected String name;         // ← protected
    
    protected void displayInfo() { // ← protected
        System.out.println("Name: " + name);
    }
}

Scope ของ protected

text┌─────────────────────────────────┐
│    com.university               │
│                                 │
│  ┌────────────────┐             │
│  │ Class Person   │             │
│  │ (protected)    │             │
│  │                │             │
│  │ protected name │             │
│  └────────────────┘             │
│           △                     │
│           │                     │
│  ┌────────────────┐             │
│  │ Class Student  │             │
│  │ (same package) │             │
│  │                │             │
│  │ ✓ เข้าถึงได้  │             │
│  │   (protected)  │             │
│  └────────────────┘             │
│                                 │
└─────────────────────────────────┘

┌─────────────────────────────────┐
│    com.school                   │
│                                 │
│  ┌────────────────┐             │
│  │ Class Student  │             │
│  │ extends Person │             │
│  │ (subclass)     │             │
│  │                │             │
│  │ ✓ เข้าถึงได้  │             │
│  │   (subclass!)  │             │
│  └────────────────┘             │
│                                 │
└─────────────────────────────────┘

ตัวอย่าง: protected กับ Inheritance

text// File 1: src/com/university/Person.java
package com.university;

public class Person {
    protected String name;              // ← protected
    
    protected void displayInfo() {
        System.out.println("Name: " + name);
    }
}

// File 2: src/com/university/Student.java
package com.university;                 // Same package

public class Student extends Person {   // Subclass
    public static void main(String[] args) {
        Student student = new Student();
        
        // ✓ Same package → เข้าถึงได้
        student.name = "John";           // ✓ OK
        student.displayInfo();           // ✓ OK
    }
}

// File 3: src/com/school/Teacher.java
package com.school;                     // Different package

import com.university.Person;

public class Teacher extends Person {   // Subclass (different package)
    public static void main(String[] args) {
        Teacher teacher = new Teacher();
        
        // ✓ Subclass → เข้าถึงได้
        teacher.name = "Dr. Smith";      // ✓ OK (protected + subclass)
        teacher.displayInfo();           // ✓ OK (protected + subclass)
    }
}

// File 4: src/com/school/Admin.java
package com.school;

import com.university.Person;

public class Admin {
    public static void main(String[] args) {
        Person person = new Person();
        
        // ❌ Different package, ไม่ใช่ subclass → ไม่ได้
        // person.name = "John";           // ❌ ERROR!
        // person.displayInfo();           // ❌ ERROR!
    }
}

ตารางเปรียบเทียบ 4 Access Modifiers

ตารางเข้าถึง

text┌────────────┬──────────┬──────────┬──────────┬──────────┐
│ Modifier   │ Class    │ Package  │ Subclass │ Others   │
│            │ (same)   │ (same)   │ (any)    │ (any)    │
├────────────┼──────────┼──────────┼──────────┼──────────┤
│ private    │    ✓     │    ✗     │    ✗     │    ✗     │
│ default    │    ✓     │    ✓     │    ✗     │    ✗     │
│ protected  │    ✓     │    ✓     │    ✓     │    ✗     │
│ public     │    ✓     │    ✓     │    ✓     │    ✓     │
└────────────┴──────────┴──────────┴──────────┴──────────┘

ตัวอักษรเพื่อจำ

textPrivate:    ✓ (ตัวเอง)
Default:    ✓ (ตัวเอง + Package)
Protected:  ✓ (ตัวเอง + Package + Subclass)
Public:     ✓ (ทุกที่)

 <─ แคบ        กว้าง ─>

ตัวอย่างที่ 1: Student Class ทั้ง 4 Modifiers

javapublic class Student {
    // 1. private - เข้าถึงได้เฉพาะใน class นี้
    private String studentID;
    private double gpa;
    
    // 2. default - เข้าถึงได้ใน package เดียวกัน
    int year;
    
    // 3. protected - เข้าถึงได้ใน package เดียวกัน + subclass
    protected String name;
    
    // 4. public - เข้าถึงได้ทุกที่
    public String email;
    
    // Methods ต่างๆ
    
    // private method
    private void calculateGPA() {
        // ...
    }
    
    // default method
    void updateYear() {
        year++;
    }
    
    // protected method
    protected void displayName() {
        System.out.println(name);
    }
    
    // public method
    public void displayInfo() {
        System.out.println("ID: " + studentID);
        System.out.println("Name: " + name);
        System.out.println("Year: " + year);
        System.out.println("Email: " + email);
    }
}

วิธีใช้จากที่ต่างๆ

java// ใน com.university package
public class Course {
    public static void main(String[] args) {
        Student student = new Student();
        
        // ✓ ทั้งหมดเข้าถึงได้ (same package)
        student.year = 2;           // ✓ default OK
        student.name = "John";      // ✓ protected OK
        student.email = "john@uni"; // ✓ public OK
        student.displayInfo();      // ✓ public OK
        student.updateYear();       // ✓ default OK
        student.displayName();      // ✓ protected OK
        
        // ❌ ไม่ได้เข้าถึง private
        // student.studentID = "6501001";  // ❌ ERROR!
        // student.gpa = 3.75;             // ❌ ERROR!
        // student.calculateGPA();         // ❌ ERROR!
    }
}

// ใน com.school package (different package)
public class Admin {
    public static void main(String[] args) {
        Student student = new Student();
        
        // ✓ เข้าถึงได้เฉพาะ public
        student.email = "john@school";  // ✓ public OK
        student.displayInfo();          // ✓ public OK
        
        // ❌ ไม่ได้เข้าถึง private, default, protected
        // student.year = 2;             // ❌ ERROR! default
        // student.name = "John";        // ❌ ERROR! protected
        // student.studentID = "6501001";// ❌ ERROR! private
        // student.updateYear();         // ❌ ERROR! default
        // student.displayName();        // ❌ ERROR! protected
    }
}

// Subclass ใน com.school package
public class GraduateStudent extends Student {
    public static void main(String[] args) {
        GraduateStudent grad = new GraduateStudent();
        
        // ✓ Subclass เข้าถึง protected + public + default (same package)
        grad.year = 1;              // ✓ default (same package)
        grad.name = "Jane";         // ✓ protected (subclass)
        grad.email = "jane@uni";    // ✓ public
        grad.displayName();         // ✓ protected (subclass)
        
        // ❌ ยังไม่ได้เข้าถึง private
        // grad.studentID = "6501001"; // ❌ ERROR! private
    }
}

ตัวอย่างที่ 2: Bank Account ด้วย 4 Modifiers

javapublic class BankAccount {
    // private - เข้าถึงได้เฉพาะใน class
    private String accountNumber;
    private double balance;
    private ArrayList<String> transactionLog;
    
    // default - เข้าถึงได้ใน package
    int dailyWithdrawalCount;
    
    // protected - เข้าถึงได้ใน package + subclass
    protected String accountHolder;
    
    // public - เข้าถึงได้ทุกที่
    public String bankName;
    
    // Constructor
    public BankAccount(String accountNumber, String holder, double initial) {
        setAccountNumber(accountNumber);
        this.accountHolder = holder;
        this.balance = initial;
        this.transactionLog = new ArrayList<>();
        this.dailyWithdrawalCount = 0;
        this.bankName = "National Bank";
    }
    
    // ===== Private Methods =====
    private void setAccountNumber(String number) {
        if (number == null || number.isEmpty()) {
            throw new IllegalArgumentException("Invalid account number");
        }
        this.accountNumber = number;
    }
    
    private void logTransaction(String transaction) {
        transactionLog.add(transaction);
    }
    
    private boolean canWithdraw(double amount) {
        return amount <= balance && dailyWithdrawalCount < 3;
    }
    
    // ===== Default Methods (package-only) =====
    void resetDailyCount() {
        dailyWithdrawalCount = 0;
    }
    
    void auditAccount() {
        System.out.println("Account Audit: " + accountNumber);
        System.out.println("Balance: " + balance);
        System.out.println("Transactions: " + transactionLog.size());
    }
    
    // ===== Protected Methods (package + subclass) =====
    protected String getAccountDetails() {
        return "Account: " + accountNumber + ", Holder: " + accountHolder;
    }
    
    protected void updateBalance(double amount) {
        this.balance += amount;
    }
    
    // ===== Public Methods =====
    public double getBalance() {
        return balance;
    }
    
    public void deposit(double amount) {
        if (amount <= 0) {
            throw new IllegalArgumentException("Amount must be positive");
        }
        this.balance += amount;
        logTransaction("Deposit: " + amount);
        System.out.println("✓ Deposited: " + amount);
    }
    
    public void withdraw(double amount) {
        if (!canWithdraw(amount)) {
            throw new IllegalArgumentException("Cannot withdraw");
        }
        this.balance -= amount;
        this.dailyWithdrawalCount++;
        logTransaction("Withdrawal: " + amount);
        System.out.println("✓ Withdrawn: " + amount);
    }
    
    public void displayInfo() {
        System.out.printf("Bank: %s | Account: %s | Holder: %s | Balance: %.2f\n",
                         bankName, accountNumber, accountHolder, balance);
    }
}

Best Practices: เลือก Modifier ที่ถูก

1. ทั่วไป: ใช้ private แรก

textStep 1: ทำให้ private
   ↓
Step 2: ถ้าต้องใช้จากคน่ะ class → เปลี่ยนเป็น protected
   ↓
Step 3: ถ้าต้องใช้จากทุกที่ → เปลี่ยนเป็น public

2. Attributes: เกือบทั้งหมด private

java// ✓ ดี: Attributes เป็น private
public class Person {
    private String name;
    private int age;
    private String email;
    
    // Expose ผ่าน getter/setter
    public String getName() { return name; }
    public void setName(String name) { this.name = name; }
}

// ❌ ไม่ดี: Attributes เป็น public
public class PersonBad {
    public String name;    // ❌ ใครก็เปลี่ยนได้
    public int age;        // ❌ ใครก็เปลี่ยนได้
    public String email;   // ❌ ใครก็เปลี่ยนได้
}

3. Methods: อยู่ที่ว่า

text┌────────────────────────────────────┐
│ Helper methods             private │
│ (ใช้เฉพาะใน class)                 │
│                                    │
│ Utility methods in package default │
│ (ใช้ใน package เดียวกัน)           │
│                                    │
│ Overridable methods      protected │
│ (ใช้ใน subclass)                   │
│                                    │
│ Main business methods      public  │
│ (ใช้ได้ทุกที่)                     │
└────────────────────────────────────┘

4. Constants: เกือบทั้งหมด public static final

javapublic class Config {
    public static final double PI = 3.14159;
    public static final int MAX_STUDENTS = 100;
    public static final String DATABASE_URL = "jdbc:mysql://...";
    
    // ไม่ต้องซ่อน constants (ค่าคงที่ไม่เปลี่ยน)
}

ตัวอย่างที่ 3: Temperature Class ด้วย Modifiers

javapublic class Temperature {
    // private - internal representation
    private double kelvin;
    
    // public static final - constant
    public static final double ABSOLUTE_ZERO = 0;
    
    // Constructor
    public Temperature(double celsius) {
        setCelsius(celsius);
    }
    
    // ===== Private Helper =====
    private void validate(double celsius) {
        if (celsius < ABSOLUTE_ZERO - 273.15) {
            throw new IllegalArgumentException("Below absolute zero");
        }
    }
    
    // ===== Public Getters (interface) =====
    public double getCelsius() {
        return kelvin - 273.15;
    }
    
    public double getFahrenheit() {
        return (kelvin - 273.15) * 9 / 5 + 32;
    }
    
    public double getKelvin() {
        return kelvin;
    }
    
    // ===== Public Setters (interface) =====
    public void setCelsius(double celsius) {
        validate(celsius);
        this.kelvin = celsius + 273.15;
    }
    
    public void setFahrenheit(double fahrenheit) {
        setCelsius((fahrenheit - 32) * 5 / 9);
    }
    
    // ===== Public Display =====
    public void displayInfo() {
        System.out.printf("C: %.2f | F: %.2f | K: %.2f\n",
                         getCelsius(), getFahrenheit(), getKelvin());
    }
}

Modifier Strategy:

  • private double kelvin – ซ่อน internal representation
  • public static final ABSOLUTE_ZERO – constant ใช้ได้ทุกที่
  • private validate() – helper method ใน class
  • public get/set methods – interface สำหรับผู้ใช้

ตัวอย่างที่ 4: Package Structure

textcom.university/
├── models/
│   ├── Person.java (base class)
│   │   - private id, ssn
│   │   - protected name, email
│   │   - public getters
│   │
│   └── Student.java (extends Person)
│       - private gpa, courses
│       - default year (package-only)
│       - protected updateGPA()
│       - public study()
│
├── services/
│   └── StudentService.java
│       - Can access: public + default (same package)
│       - Cannot access: private
│
└── util/
    └── Logger.java (different sub-package)
        - Can access: public only

ตัวอย่างที่ 5: นักศึกษาที่ศึกษา OOP

java// File: src/com/university/models/Student.java
package com.university.models;

public class Student {
    // PRIVATE - ข้อมูลส่วนตัว
    private String studentID;
    private double gpa;
    private ArrayList<String> courseHistory;
    
    // DEFAULT - ใช้ใน package นี้
    int enrollmentYear;
    
    // PROTECTED - ใช้ใน subclass
    protected String email;
    
    // PUBLIC - ใช้ได้ทุกที่
    public String name;
    
    public Student(String id, String name) {
        setStudentID(id);
        this.name = name;
        this.gpa = 0;
        this.courseHistory = new ArrayList<>();
    }
    
    // PRIVATE METHOD - เข้าถึงเฉพาะใน class
    private void setStudentID(String id) {
        if (id == null || id.isEmpty()) {
            throw new IllegalArgumentException("Invalid ID");
        }
        this.studentID = id;
    }
    
    // DEFAULT METHOD - ใช้ใน package
    void updateEnrollmentYear(int year) {
        this.enrollmentYear = year;
    }
    
    // PROTECTED METHOD - ใช้ใน subclass
    protected void setEmail(String email) {
        this.email = email;
    }
    
    // PUBLIC METHOD - ใช้ได้ทุกที่
    public double getGPA() {
        return gpa;
    }
    
    public void study() {
        gpa = Math.min(gpa + 0.1, 4.0);
    }
    
    public void displayInfo() {
        System.out.printf("ID: %s | Name: %s | GPA: %.2f\n",
                         studentID, name, gpa);
    }
}

// File: src/com/university/models/GraduateStudent.java
package com.university.models;

public class GraduateStudent extends Student {
    // Can access: public, protected, default (same package)
    // Cannot access: private
    
    public GraduateStudent(String id, String name) {
        super(id, name);
        this.enrollmentYear = 5;  // ✓ default OK
        this.setEmail("grad@uni"); // ✓ protected OK
    }
    
    public void researchProject() {
        this.study();  // ✓ public OK
        
        // ❌ ไม่ได้:
        // this.gpa = 4.0;  // private
        // this.studentID = "...";  // private
    }
}

// File: src/com/university/services/StudentService.java
package com.university.services;

import com.university.models.Student;

public class StudentService {
    public void enrollStudent(Student student) {
        // ✓ เข้าถึง public + default (same package)
        student.study();  // ✓ public
        student.displayInfo();  // ✓ public
        
        // ❌ ไม่ได้:
        // student.gpa = 4.0;  // private
        // student.setStudentID("...");  // private
    }
}

// File: src/com/school/admin/AdminPanel.java
package com.school.admin;

import com.university.models.Student;

public class AdminPanel {
    public void adminFunction() {
        Student student = new Student("123", "John");
        
        // ✓ เข้าถึงเฉพาะ public (different package)
        student.name = "Jane";  // ✓ public
        student.study();  // ✓ public
        student.displayInfo();  // ✓ public
        
        // ❌ ไม่ได้ (different package):
        // student.gpa = 4.0;  // private
        // student.email = "...";  // protected
        // student.enrollmentYear = 5;  // default
    }
}

สรุป: 4 Access Modifiers

text┌─────────────────────────────────────────┐
│  PRIVATE                                │
│  ├─ Use for: ส่วนตัว, internal data   │
│  ├─ Accessible: ใน class นั้นเท่านั้น │
│  └─ Example: private String password   │
│                                         │
│  DEFAULT                               │
│  ├─ Use for: package utility           │
│  ├─ Accessible: ใน package เดียวกัน  │
│  └─ Example: void packageMethod()      │
│                                         │
│  PROTECTED                              │
│  ├─ Use for: inheritance-related       │
│  ├─ Accessible: package + subclass     │
│  └─ Example: protected String base     │
│                                         │
│  PUBLIC                                │
│  ├─ Use for: ส่วนต่อต่างลายไปทั่วไป     │
│  ├─ Accessible: ทุกที่                 │
│  └─ Example: public void doSomething() │
│                                         │
└─────────────────────────────────────────┘

Guide: เลือก Modifier อย่างไร?

textQuestion 1: Attributes?
├─ YES → ใช้ PRIVATE เกือบทั้งหมด
└─ NO → ไปคำถาม 2

Question 2: ต้องใช้จากนอก class?
├─ NO → ใช้ PRIVATE
├─ YES, ต้อง package → ใช้ DEFAULT
├─ YES, ต้อง subclass → ใช้ PROTECTED
└─ YES, ทุกที่ → ใช้ PUBLIC

Result:
───────
private > default > protected > public
(เลือก "แคบ" ที่สุด ที่ยังใช้ได้)