บทนำ: ทำไมต้อง 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: คืออะไร?
}
ปัญหา:
- ❌ ไม่รู้
privatevspublicต่างกันไง - ❌ ไม่รู้
protectedใช้กับไหน - ❌ ไม่รู้
defaultทำไมต้องมี
ยาวไปอยากเลือกอ่าน
- บทนำ: ทำไมต้อง Access Modifiers?
- Access Modifiers ใน Java
- โครงสร้างทั่วไป
- 1. private: เข้าถึงได้เฉพาะใน Class นี้
- private คืออะไร?
- Scope ของ private
- ตัวอย่าง: private ใน BankAccount
- 2. public: เข้าถึงได้ทุกที่
- public คืออะไร?
- Scope ของ public
- ตัวอย่าง: public ใน Different Packages
- 3. default (Package-Private): เข้าถึงได้เฉพาะใน Package เดียวกัน
- default คืออะไร?
- Scope ของ default
- ตัวอย่าง: default vs public
- 4. protected: เข้าถึงได้ใน Package เดียวกัน และ Subclass
- protected คืออะไร?
- Scope ของ protected
- ตัวอย่าง: protected กับ Inheritance
- ตารางเปรียบเทียบ 4 Access Modifiers
- ตารางเข้าถึง
- ตัวอักษรเพื่อจำ
- ตัวอย่างที่ 1: Student Class ทั้ง 4 Modifiers
- วิธีใช้จากที่ต่างๆ
- ตัวอย่างที่ 2: Bank Account ด้วย 4 Modifiers
- Best Practices: เลือก Modifier ที่ถูก
- 1. ทั่วไป: ใช้ private แรก
- 2. Attributes: เกือบทั้งหมด private
- 3. Methods: อยู่ที่ว่า
- 4. Constants: เกือบทั้งหมด public static final
- ตัวอย่างที่ 3: Temperature Class ด้วย Modifiers
- ตัวอย่างที่ 4: Package Structure
- ตัวอย่างที่ 5: นักศึกษาที่ศึกษา OOP
- สรุป: 4 Access Modifiers
- 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 = “คุ้มครอง” เข้าถึงได้:
- ใน package เดียวกัน ✓
- ใน 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 representationpublic static final ABSOLUTE_ZERO– constant ใช้ได้ทุกที่private validate()– helper method ใน classpublic 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
(เลือก "แคบ" ที่สุด ที่ยังใช้ได้)
