บทนำ: ความสัมพันธ์ระหว่าง Class และ Object
ในบทที่แล้ว เราเข้าใจว่า Object มี State และ Behavior แต่ว่า Object มาจากไหน?
คำตอบคือ: มาจาก Class
Class และ Object มีความสัมพันธ์ดังนี้:
| แนวคิด | ความหมาย | ตัวอย่าง |
|---|---|---|
| Class | แบบพิมพ์เขียว (Blueprint) | หลักการวิธีทำรถยนต์ |
| Object | สิ่งของจริงที่สร้างจาก Class | รถยนต์คันนี้ (Toyota Corolla สีแดง) |
ยาวไปอยากเลือกอ่าน
- บทนำ: ความสัมพันธ์ระหว่าง Class และ Object
- Class: แบบพิมพ์เขียว (Blueprint)
- Class คืออะไร?
- ตัวอย่าง: Class ในการเขียนโปรแกรม
- Object: อินสแตนซ์ (Instance)
- Object คืออะไร?
- วิธีสร้าง Object จาก Class
- ความแตกต่างระหว่าง Class และ Object
- ตัวอย่างที่ 1: BankAccount
- Class: BankAccount (แบบแผน)
- Objects: Instances ของ BankAccount
- การใช้งาน Objects
- ตัวอย่างที่ 2: Car
- Class: Car (แบบแผน)
- Objects: Instances ของ Car
- ทำไมต้องแยก Class และ Object?
- ปัญหา: ไม่มี Class
- วิธี: ใช้ Class
- ความเป็นอิสระของ Objects
- Objects เป็นอิสระจากกัน
- ตัวอย่างที่ 3: Student Management System
- Class: Student (เขียนครั้งเดียว)
- Objects: Instances ของ Student (สร้างหลายตัว)
- ตัวอย่างที่ 4: Game Characters
- Class: GameCharacter
- Objects: Multiple Characters (เกมกำลังแสดง)
- Visual: Class vs Objects
- ดูภาพรวม
- สรุป: Class เป็นแม่แบบ, Object เป็นอินสแตนซ์
- Analogy
- ตัวอย่างสุดท้าย: Restaurant Reservation System
- Class: Restaurant
- Objects: Multiple Restaurants
- ข้อสังเกต: Class vs Object
- Class
- Object
Class: แบบพิมพ์เขียว (Blueprint)
Class คืออะไร?
Class คือ แบบแผน ที่บ่งบอกว่า:
- Object ที่สร้างจาก Class นี้จะมีข้อมูลอะไร (State)
- Object ที่สร้างจาก Class นี้จะทำอะไรได้บ้าง (Behavior)
ตัวอย่างในชีวิตจริง:
textClass: Vehicle
┌────────────────────┐
│ Blueprint ของรถ │
├────────────────────┤
│ State ที่ต้องมี: │
│ - brand │
│ - color │
│ - speed │
│ - fuelLevel │
├────────────────────┤
│ Behavior ที่ต้องมี:│
│ - start() │
│ - accelerate() │
│ - brake() │
│ - stop() │
└────────────────────┘
ตัวอย่าง: Class ในการเขียนโปรแกรม
java// นี่คือ CLASS - แบบพิมพ์เขียว
public class Student {
// State - ข้อมูลที่ object ต้องมี
private String studentID;
private String name;
private double gpa;
private int year;
// Constructor - สร้าง object
public Student(String studentID, String name, double gpa, int year) {
this.studentID = studentID;
this.name = name;
this.gpa = gpa;
this.year = year;
}
// Behavior - สิ่งที่ object ทำได้
public void study() {
// เรียน
this.gpa += 0.1;
}
public void displayInfo() {
System.out.println("ID: " + studentID);
System.out.println("Name: " + name);
System.out.println("GPA: " + gpa);
}
}
Class นี้บอกว่า:
- Student object ต้องมี studentID, name, gpa, year
- Student object สามารถ study() และ displayInfo()
แต่ ยังไม่มี object จริงๆ – เพียงแบบแผนเท่านั้น
Object: อินสแตนซ์ (Instance)
Object คืออะไร?
Object คือ สิ่งของจริง ที่สร้างจาก Class
เรียกว่า Instance เพราะ object คือ หนึ่งตัวอย่าง ของ Class
textClass: Student (แบบแผน)
↓
├─→ Object 1: john (Instance 1 - จริงๆ)
├─→ Object 2: jane (Instance 2 - จริงๆ)
└─→ Object 3: bob (Instance 3 - จริงๆ)
ทั้ง john, jane, bob คือ Instance ของ Class Student
วิธีสร้าง Object จาก Class
java// syntax:
ClassName objectName = new ClassName(parameters);
// ตัวอย่าง:
Student john = new Student("6501001", "John Doe", 3.75, 2);
Student jane = new Student("6501002", "Jane Smith", 3.50, 2);
Student bob = new Student("6501003", "Bob Johnson", 3.90, 1);
สิ่งที่เกิดขึ้น:
text1. new Student(...)
↓ สร้างพื้นที่เก็บข้อมูลในหน่วยความจำ
↓
2. Student(...)
↓ เรียก Constructor เพื่อกำหนดค่าเริ่มต้น
↓
3. john = ...
↓ เก็บ reference ของ object
↓
ผลลัพธ์: john กลายเป็น object ของ Class Student
ความแตกต่างระหว่าง Class และ Object
ตัวอย่างที่ 1: BankAccount
Class: BankAccount (แบบแผน)
javapublic class BankAccount {
// State
private String accountNumber;
private String accountHolder;
private double balance;
// Constructor
public BankAccount(String accountNumber, String accountHolder, double balance) {
this.accountNumber = accountNumber;
this.accountHolder = accountHolder;
this.balance = balance;
}
// Behavior
public void deposit(double amount) {
balance += amount;
}
public void withdraw(double amount) {
if (balance >= amount) {
balance -= amount;
}
}
public void displayBalance() {
System.out.println("Balance: " + balance);
}
}
Class นี้เป็นแบบแผน – ยังไม่มี account จริงๆ
Objects: Instances ของ BankAccount
java// สร้าง 3 objects จาก Class BankAccount
// Object 1: account ของ John
BankAccount johnAccount = new BankAccount("ACC001", "John Doe", 50000);
// Object 2: account ของ Jane
BankAccount janeAccount = new BankAccount("ACC002", "Jane Smith", 75000);
// Object 3: account ของ Bob
BankAccount bobAccount = new BankAccount("ACC003", "Bob Johnson", 30000);
ตอนนี้มี 3 objects จริงๆ:
textjohnAccount:
├─ accountNumber = "ACC001"
├─ accountHolder = "John Doe"
└─ balance = 50000
janeAccount:
├─ accountNumber = "ACC002"
├─ accountHolder = "Jane Smith"
└─ balance = 75000
bobAccount:
├─ accountNumber = "ACC003"
├─ accountHolder = "Bob Johnson"
└─ balance = 30000
การใช้งาน Objects
javapublic class BankDemo {
public static void main(String[] args) {
// สร้าง 3 objects
BankAccount johnAccount = new BankAccount("ACC001", "John Doe", 50000);
BankAccount janeAccount = new BankAccount("ACC002", "Jane Smith", 75000);
// เรียก Behavior ของ johnAccount
johnAccount.deposit(10000); // ฝากเงิน
johnAccount.displayBalance(); // Output: Balance: 60000
// เรียก Behavior ของ janeAccount
janeAccount.withdraw(20000); // ถอนเงิน
janeAccount.displayBalance(); // Output: Balance: 55000
// สรุป
System.out.println("johnAccount balance: 60000");
System.out.println("janeAccount balance: 55000");
System.out.println("โดยทั้งสองเป็น objects (instances) ของ Class BankAccount");
}
}
Output:
textBalance: 60000
Balance: 55000
johnAccount balance: 60000
janeAccount balance: 55000
โดยทั้งสองเป็น objects (instances) ของ Class BankAccount
ตัวอย่างที่ 2: Car
Class: Car (แบบแผน)
textClass Car (แบบแผน)
┌─────────────────────────────┐
│ State: │
│ - brand │
│ - model │
│ - color │
│ - speed │
│ - fuelLevel │
│ │
│ Behavior: │
│ - start() │
│ - accelerate() │
│ - brake() │
│ - refuel() │
└─────────────────────────────┘
Class นี้บอก "รถควรมีข้อมูลและทำงานอย่างไร"
แต่ยังไม่มีรถจริง
Objects: Instances ของ Car
textInstance 1: myCar
┌──────────────────────┐
│ brand = "Toyota" │
│ model = "Corolla" │
│ color = "Red" │
│ speed = 0 │
│ fuelLevel = 50 │
└──────────────────────┘
Instance 2: yourCar
┌──────────────────────┐
│ brand = "Honda" │
│ model = "Civic" │
│ color = "Blue" │
│ speed = 0 │
│ fuelLevel = 100 │
└──────────────────────┘
Instance 3: carAtShop
┌──────────────────────┐
│ brand = "BMW" │
│ model = "X5" │
│ color = "Black" │
│ speed = 0 │
│ fuelLevel = 30 │
└──────────────────────┘
ทั้ง 3 objects มาจาก Class Car เดียวกัน
แต่มี State ต่างกัน
ทำไมต้องแยก Class และ Object?
ปัญหา: ไม่มี Class
java// ❌ ไม่ใช้ Class - ต้องเขียนโค้ดซ้ำซ้อน
// Account 1 ของ John
String account1Number = "ACC001";
String account1Holder = "John Doe";
double account1Balance = 50000;
// Account 2 ของ Jane
String account2Number = "ACC002";
String account2Holder = "Jane Smith";
double account2Balance = 75000;
// Account 3 ของ Bob
String account3Number = "ACC003";
String account3Holder = "Bob Johnson";
double account3Balance = 30000;
// Behavior: ฝากเงิน (ต้องเขียนซ้ำ 3 ครั้ง!)
account1Balance += 10000;
account2Balance += 20000;
account3Balance += 5000;
// ถ้ามี 1000 accounts ต้องเขียน 3000 variables!
วิธี: ใช้ Class
java// ✓ ใช้ Class - เขียนครั้งเดียว ใช้หลายครั้ง
// Class BankAccount (เขียนครั้งเดียว)
public class BankAccount {
private String accountNumber;
private String accountHolder;
private double balance;
public void deposit(double amount) {
balance += amount;
}
}
// สร้าง 1000 objects ใน loop!
BankAccount[] accounts = new BankAccount[1000];
for (int i = 0; i < 1000; i++) {
accounts[i] = new BankAccount(...);
}
// ใช้ทั้งหมด
for (BankAccount account : accounts) {
account.deposit(1000);
}
ข้อดี:
- ✓ เขียน Class ครั้งเดียว
- ✓ สร้าง objects ได้หลายชั้นไป
- ✓ ลดการเขียนโค้ดซ้ำ
- ✓ ง่ายต่อการดูแล
ความเป็นอิสระของ Objects
Objects เป็นอิสระจากกัน
javaBankAccount account1 = new BankAccount("ACC001", "John", 50000);
BankAccount account2 = new BankAccount("ACC002", "Jane", 75000);
// account1 ทำสิ่งใดสิ่งหนึ่ง
account1.deposit(10000);
// account1.balance = 60000
// account2 ไม่ได้รับผลกระทบ
// account2.balance = 75000 (ยังเหมือนเดิม)
System.out.println(account1.getBalance()); // 60000
System.out.println(account2.getBalance()); // 75000
ทำไม?
- account1 และ account2 เป็น objects ต่างกัน
- มี หน่วยความจำต่างกัน
- เปลี่ยนแปลง state ของ account1 ไม่ส่งผลกระทบ account2
ตัวอย่างที่ 3: Student Management System
Class: Student (เขียนครั้งเดียว)
javapublic class Student {
// State
private String studentID;
private String name;
private double gpa;
private int year;
// Constructor
public Student(String studentID, String name, double gpa, int year) {
this.studentID = studentID;
this.name = name;
this.gpa = gpa;
this.year = year;
}
// Behavior
public void updateGPA(double newGPA) {
this.gpa = newGPA;
}
public void displayInfo() {
System.out.printf("ID: %s, Name: %s, GPA: %.2f, Year: %d\n",
studentID, name, gpa, year);
}
}
Objects: Instances ของ Student (สร้างหลายตัว)
javapublic class StudentDemo {
public static void main(String[] args) {
// สร้าง 5 objects จาก Class Student
Student student1 = new Student("6501001", "John Doe", 3.75, 2);
Student student2 = new Student("6501002", "Jane Smith", 3.50, 2);
Student student3 = new Student("6501003", "Bob Johnson", 3.90, 1);
Student student4 = new Student("6501004", "Alice Brown", 3.45, 3);
Student student5 = new Student("6501005", "Tom Wilson", 3.80, 1);
// เรียก Behavior ของแต่ละ object
System.out.println("=== Before Update ===");
student1.displayInfo();
student2.displayInfo();
student3.displayInfo();
// เปลี่ยน state ของ student1
student1.updateGPA(3.85);
// student2 และ student3 ไม่เปลี่ยน
System.out.println("\n=== After Update (only student1) ===");
student1.displayInfo();
student2.displayInfo(); // ยังเหมือนเดิม
student3.displayInfo(); // ยังเหมือนเดิม
// เปลี่ยน state ของ student3
student3.updateGPA(4.0);
System.out.println("\n=== After Update (student3) ===");
student3.displayInfo(); // เปลี่ยน
student1.displayInfo(); // ยังเหมือนเดิม
}
}
Output:
text=== Before Update ===
ID: 6501001, Name: John Doe, GPA: 3.75, Year: 2
ID: 6501002, Name: Jane Smith, GPA: 3.50, Year: 2
ID: 6501003, Name: Bob Johnson, GPA: 3.90, Year: 1
=== After Update (only student1) ===
ID: 6501001, Name: John Doe, GPA: 3.85, Year: 2
ID: 6501002, Name: Jane Smith, GPA: 3.50, Year: 2
ID: 6501003, Name: Bob Johnson, GPA: 3.90, Year: 1
=== After Update (student3) ===
ID: 6501003, Name: Bob Johnson, GPA: 4.00, Year: 1
ID: 6501001, Name: John Doe, GPA: 3.85, Year: 2
ตัวอย่างที่ 4: Game Characters
Class: GameCharacter
javapublic class GameCharacter {
// State
private String characterName;
private int level;
private int health;
private int experience;
// Constructor
public GameCharacter(String characterName, int level) {
this.characterName = characterName;
this.level = level;
this.health = 100;
this.experience = 0;
}
// Behavior
public void takeDamage(int damage) {
health -= damage;
if (health < 0) health = 0;
}
public void heal(int amount) {
health += amount;
if (health > 100) health = 100;
}
public void gainXP(int xp) {
experience += xp;
if (experience >= 100) {
level++;
experience = 0;
}
}
public void displayStatus() {
System.out.printf("Character: %s, Level: %d, HP: %d, XP: %d\n",
characterName, level, health, experience);
}
}
Objects: Multiple Characters (เกมกำลังแสดง)
javapublic class GameDemo {
public static void main(String[] args) {
// สร้าง 3 character objects
GameCharacter hero = new GameCharacter("Hero", 5);
GameCharacter enemy1 = new GameCharacter("Goblin", 3);
GameCharacter enemy2 = new GameCharacter("Orc", 4);
System.out.println("=== Initial State ===");
hero.displayStatus();
enemy1.displayStatus();
enemy2.displayStatus();
System.out.println("\n=== Battle ===");
// Hero ถูกโจมตี
hero.takeDamage(20);
System.out.println("Hero was attacked!");
hero.displayStatus();
// Hero กินยา
hero.heal(15);
System.out.println("Hero healed!");
hero.displayStatus();
// Hero ชนะศัตรู
hero.gainXP(50);
System.out.println("Hero defeated Goblin!");
hero.displayStatus();
// Enemy1 ถูกฆ่า
enemy1.takeDamage(100);
System.out.println("Goblin died!");
enemy1.displayStatus();
// Hero ชนะศัตรูต่อ
hero.gainXP(100);
System.out.println("Hero defeated Orc and leveled up!");
hero.displayStatus();
System.out.println("\n=== Final State ===");
System.out.println("Hero is alive: " + (hero.health > 0));
System.out.println("Goblin is alive: " + (enemy1.health > 0));
System.out.println("Orc is alive: " + (enemy2.health > 0));
}
}
Output:
text=== Initial State ===
Character: Hero, Level: 5, HP: 100, XP: 0
Character: Goblin, Level: 3, HP: 100, XP: 0
Character: Orc, Level: 4, HP: 100, XP: 0
=== Battle ===
Hero was attacked!
Character: Hero, Level: 5, HP: 80, XP: 0
Hero healed!
Character: Hero, Level: 5, HP: 95, XP: 0
Hero defeated Goblin!
Character: Hero, Level: 5, HP: 95, XP: 50
Goblin died!
Character: Goblin, Level: 3, HP: 0, XP: 0
Hero defeated Orc and leveled up!
Character: Hero, Level: 6, HP: 95, XP: 0
=== Final State ===
Hero is alive: true
Goblin is alive: false
Orc is alive: false
Visual: Class vs Objects
ดูภาพรวม
text┌─────────────────────────────────────┐
│ CLASS Student │
│ (แบบแผนสำหรับสร้าง objects) │
│ │
│ Attributes: │
│ - studentID: String │
│ - name: String │
│ - gpa: double │
│ - year: int │
│ │
│ Methods: │
│ - study() │
│ - updateGPA() │
│ - displayInfo() │
└─────────────────────────────────────┘
↓ ↓ ↓
new Student new Student new Student
↓ ↓ ↓
┌──────────────────┐ ┌──────────────────┐ ┌──────────────────┐
│ OBJECT: john │ │ OBJECT: jane │ │ OBJECT: bob │
│ (Instance 1) │ │ (Instance 2) │ │ (Instance 3) │
│ │ │ │ │ │
│ studentID: │ │ studentID: │ │ studentID: │
│ "6501001" │ │ "6501002" │ │ "6501003" │
│ name: "John Doe" │ │ name: "Jane" │ │ name: "Bob" │
│ gpa: 3.75 │ │ gpa: 3.50 │ │ gpa: 3.90 │
│ year: 2 │ │ year: 2 │ │ year: 1 │
└──────────────────┘ └──────────────────┘ └──────────────────┘
สรุป: Class เป็นแม่แบบ, Object เป็นอินสแตนซ์
| แนวคิด | ความหมาย | ตัวอย่าง |
|---|---|---|
| Class | แบบพิมพ์เขียว (Blueprint) | public class Student { ... } |
| Object | สิ่องจริงที่สร้างจาก Class (Instance) | Student john = new Student(...); |
| Relationship | 1 Class สามารถสร้าง objects หลายตัว | 1 Class → ∞ Objects |
| Independence | Objects เป็นอิสระจากกัน | เปลี่ยน john ไม่ส่งผลกับ jane |
Analogy
textClass คือ: พิมพ์สำหรับทำคุ้กกี้
Object คือ: คุ้กกี้ที่ทำจากพิมพ์นั้น
- 1 พิมพ์ → ทำคุ้กกี้ได้หลายแบบ
- แต่ละคุ้กกี้ เป็นอิสระจากกัน (คุ้กกี้ตัวนึง หักหล่นไม่ส่งผลต่ออีกตัว)
ตัวอย่างสุดท้าย: Restaurant Reservation System
Class: Restaurant
javapublic class Restaurant {
// State
private String restaurantName;
private String cuisine;
private int totalTables;
private int availableTables;
private double rating;
// Constructor
public Restaurant(String restaurantName, String cuisine, int totalTables, double rating) {
this.restaurantName = restaurantName;
this.cuisine = cuisine;
this.totalTables = totalTables;
this.availableTables = totalTables;
this.rating = rating;
}
// Behavior
public boolean reserveTable(int numTables) {
if (availableTables >= numTables) {
availableTables -= numTables;
return true;
}
return false;
}
public void cancelReservation(int numTables) {
availableTables += numTables;
if (availableTables > totalTables) {
availableTables = totalTables;
}
}
public void displayStatus() {
System.out.printf("%s (%s) - Rating: %.1f ★ | Available Tables: %d/%d\n",
restaurantName, cuisine, rating, availableTables, totalTables);
}
}
Objects: Multiple Restaurants
javapublic class RestaurantDemo {
public static void main(String[] args) {
// สร้าง 3 restaurant objects
Restaurant restaurant1 = new Restaurant("Thai Palace", "Thai", 10, 4.5);
Restaurant restaurant2 = new Restaurant("Pizza House", "Italian", 8, 4.2);
Restaurant restaurant3 = new Restaurant("Sushi Master", "Japanese", 6, 4.8);
System.out.println("=== Initial State ===");
restaurant1.displayStatus();
restaurant2.displayStatus();
restaurant3.displayStatus();
System.out.println("\n=== Making Reservations ===");
// จองโต๊ะ Thai Palace 3 โต๊ะ
if (restaurant1.reserveTable(3)) {
System.out.println("Reserved 3 tables at Thai Palace");
}
restaurant1.displayStatus();
// จองโต๊ะ Pizza House 4 โต๊ะ
if (restaurant2.reserveTable(4)) {
System.out.println("Reserved 4 tables at Pizza House");
}
restaurant2.displayStatus();
// ลองจอง Sushi Master 10 โต๊ะ (ไม่พอ)
if (restaurant3.reserveTable(10)) {
System.out.println("Reserved 10 tables at Sushi Master");
} else {
System.out.println("Cannot reserve 10 tables at Sushi Master (only 6 available)");
}
restaurant3.displayStatus();
System.out.println("\n=== After More Reservations ===");
// จองโต๊ะ Sushi Master 5 โต๊ะ (พอ)
if (restaurant3.reserveTable(5)) {
System.out.println("Reserved 5 tables at Sushi Master");
}
restaurant3.displayStatus();
System.out.println("\n=== Cancellations ===");
// ยกเลิกการจอง Thai Palace 2 โต๊ะ
restaurant1.cancelReservation(2);
System.out.println("Cancelled 2 reservations at Thai Palace");
restaurant1.displayStatus();
}
}
Output:
text=== Initial State ===
Thai Palace (Thai) - Rating: 4.5 ★ | Available Tables: 10/10
Pizza House (Italian) - Rating: 4.2 ★ | Available Tables: 8/8
Sushi Master (Japanese) - Rating: 4.8 ★ | Available Tables: 6/6
=== Making Reservations ===
Reserved 3 tables at Thai Palace
Thai Palace (Thai) - Rating: 4.5 ★ | Available Tables: 7/10
Reserved 4 tables at Pizza House
Pizza House (Italian) - Rating: 4.2 ★ | Available Tables: 4/8
Cannot reserve 10 tables at Sushi Master (only 6 available)
Sushi Master (Japanese) - Rating: 4.8 ★ | Available Tables: 6/6
=== After More Reservations ===
Reserved 5 tables at Sushi Master
Sushi Master (Japanese) - Rating: 4.8 ★ | Available Tables: 1/6
=== Cancellations ===
Cancelled 2 reservations at Thai Palace
Thai Palace (Thai) - Rating: 4.5 ★ | Available Tables: 9/10
ข้อสังเกต: Class vs Object
Class
text✓ เขียนครั้งเดียว
✓ เป็น "template" อ้างอิง
✓ ไม่มี data จริงๆ
✓ อยู่ใน source code
Object
text✓ สร้างได้หลายตัว
✓ เป็น "สิ่องจริง"
✓ มี data จริงๆ ต่างกันแต่ละตัว
✓ มีอยู่ใน memory เมื่อรันโปรแกรม
บทความนี้เป็นส่วนหนึ่งของรายวิชา Object-Oriented Programming with Java สำหรับนักศึกษาวิศวกรรมคอมพิวเตอร์และวิศวกรรมซอฟต์แวร์
