บทนำ: ปัญหาของ Method ที่ต้องการ Behavior ต่างกัน
บางครั้ง subclass ต้องการ เปลี่ยนพฤติกรรม (behavior) ของ method จาก superclass เพราะตัวเองมีความเฉพาะเจาะจง
java// ❌ ปัญหา: Method เดียวกันทำ behavior เดียวกัน
public class Animal {
public void makeSound() {
System.out.println("Some generic sound");
}
}
public class Dog extends Animal {
// ใช้ makeSound() จาก Animal
// แต่ Dog ควรส่งเสียง "Woof!" ไม่ใช่ "Some generic sound"
}
// การใช้งาน
Dog dog = new Dog();
dog.makeSound(); // ❌ Output: "Some generic sound"
// ✓ ควรเป็น: "Woof!"
ปัญหา:
- ❌ Subclass ต้องการ behavior ต่างกัน
- ❌ ไม่สามารถปรับปรุง parent method ได้
- ❌ Code ไม่ยืดหยุ่น
- บทนำ: ปัญหาของ Method ที่ต้องการ Behavior ต่างกัน
- Method Overriding คืออะไร?
- Syntax: Method Overriding
- ตัวอย่างที่ 1: Simple Method Overriding
- Rules ของ Method Overriding
- Method Overriding ต้องเป็นไปตามกฎ
- ตัวอย่างที่ 2: Rules ของ Overriding
- Super Keyword คืออะไร?
- ตัวอย่างที่ 3: Super Keyword – Methods
- ตัวอย่างที่ 4: Super Keyword – Attributes
- ตัวอย่างที่ 5: Override แล้ว Super
- Common Patterns ของ Overriding
- Pattern 1: Extend Parent Behavior
- Pattern 2: Replace Parent Behavior
- Pattern 3: Conditional Super Call
- Best Practices: Overriding & Super
- 1. ใช้ @Override Annotation
- 2. ตรวจสอบ Method Signature
- 3. Super ควร ใช้อย่างสมเหตุผล
- ตัวอย่างสุดท้าย: Real-World Scenario
- สรุป
Method Overriding คืออะไร?
Method Overriding = Subclass เขียน method ใหม่ ที่มี ชื่อเดียวกับ parent แต่มี implementation ต่างกัน
textConcept:
┌──────────────────────┐
│ Animal │
│ public void sound() │ ← method ที่เป็น template
│ { print "sound" } │
└──────────────────────┘
△
│ extends
│
┌──────────────────────┐
│ Dog │
│ public void sound() │ ← override: เขียนใหม่
│ { print "Woof!" } │
└──────────────────────┘
Syntax: Method Overriding
java// Parent class
public class Parent {
public void method() {
// Parent implementation
}
}
// Child class
public class Child extends Parent {
@Override // ← Annotation (optional แต่แนะนำ)
public void method() {
// Child implementation (ต่างกับ parent)
}
}
ตัวอย่างที่ 1: Simple Method Overriding
java// SUPERCLASS
public class Animal {
protected String name;
public Animal(String name) {
this.name = name;
}
public void makeSound() {
System.out.println("Animal makes a sound");
}
}
// SUBCLASS 1
public class Dog extends Animal {
public Dog(String name) {
super(name);
}
@Override
public void makeSound() {
System.out.println(name + " says: Woof! Woof!");
}
}
// SUBCLASS 2
public class Cat extends Animal {
public Cat(String name) {
super(name);
}
@Override
public void makeSound() {
System.out.println(name + " says: Meow!");
}
}
// SUBCLASS 3
public class Cow extends Animal {
public Cow(String name) {
super(name);
}
@Override
public void makeSound() {
System.out.println(name + " says: Moo!");
}
}
// ใช้งาน
public class Main {
public static void main(String[] args) {
Dog dog = new Dog("Rex");
dog.makeSound(); // Rex says: Woof! Woof!
Cat cat = new Cat("Whiskers");
cat.makeSound(); // Whiskers says: Meow!
Cow cow = new Cow("Bessie");
cow.makeSound(); // Bessie says: Moo!
// โดยไม่ override
Animal generic = new Animal("Generic");
generic.makeSound(); // Animal makes a sound
}
}
Output:
textRex says: Woof! Woof!
Whiskers says: Meow!
Bessie says: Moo!
Animal makes a sound
คำอธิบาย:
Dog,Cat,Cowต่างก็ overridemakeSound()- แต่ละ subclass มี behavior ของตัวเอง
@Overrideannotation ช่วยให้ compiler check ว่า method ถูกต้อง
Rules ของ Method Overriding
Method Overriding ต้องเป็นไปตามกฎ
text1. ✓ Method name เหมือนกัน
2. ✓ Parameters เหมือนกัน
3. ✓ Return type เหมือนกัน (หรือ subtype)
4. ✓ Access modifier ต้อง "เท่า" หรือ "เปิด" กว่า parent
5. ✓ ไม่ควร throw exception มากขึ้น
6. ✗ ไม่ได้ override static methods
7. ✗ ไม่ได้ override final methods
ตัวอย่างที่ 2: Rules ของ Overriding
java// CORRECT OVERRIDING
public class Parent {
public void method(int x) {
System.out.println("Parent");
}
}
public class Child extends Parent {
@Override
public void method(int x) { // ✓ ถูกต้อง
System.out.println("Child");
}
}
// ❌ INCORRECT: Parameter ต่างกัน
public class WrongChild1 extends Parent {
@Override
public void method(String x) { // ❌ ERROR! Different parameter
System.out.println("Wrong");
}
}
// ❌ INCORRECT: Return type ต่างกัน
public class WrongChild2 extends Parent {
@Override
public int method(int x) { // ❌ ERROR! Different return type
return 0;
}
}
// ❌ INCORRECT: Less accessible
public class Parent2 {
public void method() {}
}
public class WrongChild3 extends Parent2 {
@Override
private void method() { // ❌ ERROR! private < public
}
}
Super Keyword คืออะไร?
super = keyword ที่ใช้เข้าถึง parent class members (methods, attributes, constructor)
textการใช้ super:
1. super.methodName() ← เรียก parent method
2. super.attributeName ← เข้าถึง parent attribute
3. super(...) ← เรียก parent constructor
ตัวอย่างที่ 3: Super Keyword – Methods
java// SUPERCLASS
public class Vehicle {
public void start() {
System.out.println("Vehicle is starting...");
}
public void stop() {
System.out.println("Vehicle is stopping...");
}
}
// SUBCLASS
public class Car extends Vehicle {
@Override
public void start() {
// ✓ เรียก parent method ก่อน
super.start();
// ✓ เพิ่ม Car-specific behavior
System.out.println("Car engine is warming up");
System.out.println("Car doors are locking");
}
@Override
public void stop() {
System.out.println("Car is applying brakes");
System.out.println("Car parking lights are on");
// ✓ เรียก parent method ที่ท้าย
super.stop();
}
}
// ใช้งาน
public class Main {
public static void main(String[] args) {
Car car = new Car();
car.start();
System.out.println();
car.stop();
}
}
Output:
textVehicle is starting...
Car engine is warming up
Car doors are locking
Car is applying brakes
Car parking lights are on
Vehicle is stopping...
คำอธิบาย:
super.start()เรียก parent method ก่อน- แล้ว Car เพิ่มเติม behavior ของตัวเอง
super.stop()เรียก parent method ที่ท้าย
ตัวอย่างที่ 4: Super Keyword – Attributes
java// SUPERCLASS
public class Person {
protected String name;
protected int age;
public Person(String name, int age) {
this.name = name;
this.age = age;
}
}
// SUBCLASS
public class Employee extends Person {
private String employeeID;
private double salary;
public Employee(String name, int age, String id, double salary) {
super(name, age); // ← เรียก parent constructor
this.employeeID = id;
this.salary = salary;
}
public void displayInfo() {
// ✓ เข้าถึง parent attributes ผ่าน super
System.out.println("Name: " + super.name);
System.out.println("Age: " + super.age);
// ✓ หรือสามารถเข้าถึงตรงๆ (protected)
System.out.println("ID: " + employeeID);
System.out.println("Salary: " + salary);
}
}
// ใช้งาน
public class Main {
public static void main(String[] args) {
Employee emp = new Employee("John", 30, "E001", 50000);
emp.displayInfo();
}
}
Output:
textName: John
Age: 30
ID: E001
Salary: 50000.0
คำอธิบาย:
super(name, age)เรียก parent constructorsuper.nameเข้าถึง parent attribute (optional ถ้า protected)- ทำให้ parent initialization สำเร็จ
ตัวอย่างที่ 5: Override แล้ว Super
java// SUPERCLASS
public class Shape {
protected String color;
public Shape(String color) {
this.color = color;
}
public void display() {
System.out.println("Shape color: " + color);
}
public double getArea() {
return 0;
}
}
// SUBCLASS 1
public class Rectangle extends Shape {
protected double width;
protected double height;
public Rectangle(String color, double w, double h) {
super(color);
this.width = w;
this.height = h;
}
@Override
public void display() {
super.display(); // ← เรียก parent method ก่อน
System.out.printf("Rectangle: %.2f x %.2f\n", width, height);
}
@Override
public double getArea() {
return width * height;
}
}
// SUBCLASS 2: extends Rectangle (multi-level)
public class Square extends Rectangle {
public Square(String color, double side) {
super(color, side, side); // ← เรียก Rectangle constructor
}
@Override
public void display() {
super.display(); // ← เรียก Rectangle display
System.out.println("This is a Square");
}
}
// ใช้งาน
public class Main {
public static void main(String[] args) {
Rectangle rect = new Rectangle("Red", 5, 10);
rect.display();
System.out.println("Area: " + rect.getArea());
System.out.println();
Square square = new Square("Blue", 4);
square.display();
System.out.println("Area: " + square.getArea());
}
}
Output:
textShape color: Red
Rectangle: 5.00 x 10.00
Area: 50.0
Shape color: Blue
Rectangle: 4.00 x 4.00
This is a Square
Area: 16.0
คำอธิบาย:
Rectangle.display()เรียกsuper.display()จากShapeSquare.display()เรียกsuper.display()จากRectangle- Constructor chain:
Square→Rectangle→Shape
Common Patterns ของ Overriding
Pattern 1: Extend Parent Behavior
javapublic class Parent {
public void process() {
System.out.println("Parent processing");
}
}
public class Child extends Parent {
@Override
public void process() {
super.process(); // ← Do parent work first
System.out.println("Child processing");
// Parent work + Child work
}
}
Pattern 2: Replace Parent Behavior
javapublic class Parent {
public void calculate() {
System.out.println("Parent calculation");
}
}
public class Child extends Parent {
@Override
public void calculate() {
System.out.println("Child calculation");
// ← ไม่เรียก super, replace ทั้งหมด
}
}
Pattern 3: Conditional Super Call
javapublic class Parent {
public void validate(int value) {
if (value >= 0) {
System.out.println("Valid");
}
}
}
public class Child extends Parent {
@Override
public void validate(int value) {
if (value > 100) {
System.out.println("Too large");
return;
}
super.validate(value); // ← เรียก parent ก็เมื่อเงื่อนไขถูก
}
}
Best Practices: Overriding & Super
1. ใช้ @Override Annotation
java// ✓ ดี: ใช้ @Override
public class Child extends Parent {
@Override
public void method() {
// ...
}
}
// ⚠️ ไม่ดี: ไม่มี @Override
public class Child extends Parent {
public void method() {
// ...
}
}
2. ตรวจสอบ Method Signature
java// ✓ ดี: Signature ตรงกัน
public class Parent {
public void method(String name, int age) {}
}
public class Child extends Parent {
@Override
public void method(String name, int age) {
// Correct override
}
}
// ❌ ไม่ดี: Signature ต่างกัน
public class Child extends Parent {
public void method(int age, String name) {
// ERROR: Different signature = new method, not override!
}
}
3. Super ควร ใช้อย่างสมเหตุผล
java// ✓ ดี: Super มี ความหมาย
@Override
public void start() {
super.start(); // ← Parent does important setup
doChildSpecificThing();
}
// ⚠️ ไม่ชำนาญ: Super ไม่ต้องการ
@Override
public void start() {
super.start(); // ← Parent method ว่าง
doThing();
}
ตัวอย่างสุดท้าย: Real-World Scenario
java// SUPERCLASS: Employee (Base template)
public class Employee {
protected String name;
protected double baseSalary;
public Employee(String name, double baseSalary) {
this.name = name;
this.baseSalary = baseSalary;
}
public double calculateSalary() {
return baseSalary;
}
public void work() {
System.out.println(name + " is working");
}
public void displayInfo() {
System.out.printf("Name: %s | Salary: %.2f\n",
name, calculateSalary());
}
}
// SUBCLASS 1: Manager
public class Manager extends Employee {
private int teamSize;
public Manager(String name, double baseSalary, int teamSize) {
super(name, baseSalary);
this.teamSize = teamSize;
}
@Override
public double calculateSalary() {
// ✓ Override: Manager gets bonus for team
return baseSalary + (teamSize * 1000);
}
@Override
public void work() {
super.work(); // Employee work
System.out.println(name + " is managing team of " + teamSize);
}
@Override
public void displayInfo() {
super.displayInfo();
System.out.println("Team Size: " + teamSize);
}
}
// SUBCLASS 2: Developer
public class Developer extends Employee {
private String programmingLanguage;
public Developer(String name, double baseSalary, String language) {
super(name, baseSalary);
this.programmingLanguage = language;
}
@Override
public double calculateSalary() {
// ✓ Override: Developer gets smaller bonus
return baseSalary * 1.05;
}
@Override
public void work() {
super.work(); // Employee work
System.out.println(name + " is coding in " + programmingLanguage);
}
@Override
public void displayInfo() {
super.displayInfo();
System.out.println("Language: " + programmingLanguage);
}
}
// ใช้งาน
public class Main {
public static void main(String[] args) {
System.out.println("=== Manager ===");
Manager manager = new Manager("Alice", 60000, 5);
manager.work();
manager.displayInfo();
System.out.println("\n=== Developer ===");
Developer dev = new Developer("Bob", 50000, "Java");
dev.work();
dev.displayInfo();
}
}
Output:
text=== Manager ===
Alice is working
Alice is managing team of 5
Name: Alice | Salary: 65000.00
Team Size: 5
=== Developer ===
Bob is working
Bob is coding in Java
Name: Bob | Salary: 52500.00
Language: Java
คำอธิบาย:
ManageroverridecalculateSalary()– บวก bonus สำหรับทีมManageroverridework()– เรียกsuper.work()ก่อน แล้ว add manager-specific workDeveloperoverride ด้วยวิธี ที่ต่างกันdisplayInfo()ใช้super.displayInfo()เพื่อแสดง base info ก่อน
สรุป
Method Overriding เป็นเครื่องมือที่ทรงพลังที่ให้ subclass สามารถ เปลี่ยนพฤติกรรมของ method ตามความต้องการของตัวเอง ในขณะที่ยังรักษา method signature ให้เหมือนกัน ด้วยการใช้ overriding เราสามารถสร้าง flexible class hierarchies ที่각 subclass สามารถ customize behavior ได้
Super keyword เป็นหนึ่งใน keywords ที่สำคัญที่สุด เพราะมันให้เราเข้าถึง parent class members ได้ ซึ่งช่วยให้เรา reuse parent functionality ไม่ต้องเขียนใหม่ทั้งหมด โดยผ่านการใช้ super() ใน constructor เราสามารถเรียก parent constructor ได้ และผ่าน super.method() เราสามารถเรียก parent method ได้
การรวม overriding และ super keyword ทำให้เราสามารถเขียน code ที่ทั้ง ยืดหยุ่น (flexibility) และ ประหยัด (reusability) ได้ เมื่อใช้กับ design pattern ที่เหมาะสม overriding จะกลายเป็นพื้นฐานของ polymorphism ซึ่งเป็นศิลปะในการเขียน OOP ที่ดี
