บทนำ: ความสัมพันธ์ระหว่าง Parent-Child Classes
เมื่อเราใช้ inheritance ชื่อเรียกจะเปลี่ยน – class ที่ให้ความสามารถ เรียกว่า Superclass (หรือ Parent Class) และ class ที่รับความสามารถ เรียกว่า Subclass (หรือ Child Class)
text┌──────────────────────┐
│ Superclass / Parent│
│ (ให้ความสามารถ) │
└──────────────────────┘
△
│ extends
│
┌─────┴─────┐
│ │
┌─────────┐ ┌─────────┐
│ Subclass│ │ Subclass│
│ (Child) │ │ (Child) │
└─────────┘ └─────────┘
- บทนำ: ความสัมพันธ์ระหว่าง Parent-Child Classes
- Terminology: Superclass vs Subclass
- คำศัพท์ที่ต้องรู้
- ตัวอย่างที่ 1: สำรวจ Superclass และ Subclass
- ลำดับชั้นของ Subclass/Superclass
- Single-Level Inheritance
- Multi-Level Inheritance
- ตัวอย่างที่ 2: Multi-Level Subclass/Superclass
- Differences: Superclass vs Subclass
- ตารางเปรียบเทียบ
- Relationship: "IS-A"
- Subclass "IS-A" Superclass
- ตัวอย่างที่ 3: Real-World Scenario
- ข้อควรระวัง: Superclass vs Subclass
- 1. Private Members ไม่ Inherit
- 2. Constructor ไม่ Inherit (แต่ต้องเรียก super())
- 3. Static Members ไม่ Override (แต่ Inherit)
- Hierarchy Best Practices
- 1. Single Superclass
- 2. Appropriate Naming
- 3. ไม่ควร Extend เกิน 3-4 Levels
- Type Compatibility
- Subclass object สามารถ assign ให้ Superclass reference ได้
- ตัวอย่างที่ 4: Type Compatibility
- สรุป
Terminology: Superclass vs Subclass
คำศัพท์ที่ต้องรู้
textSuperclass = Parent Class = Base Class
└─ class ที่ปล่อยความสามารถให้
└─ class ที่อยู่สูงสุดในลำดับชั้น
Subclass = Child Class = Derived Class
└─ class ที่รับความสามารถมา
└─ class ที่อยู่ล่างในลำดับชั้น
ตัวอย่างที่ 1: สำรวจ Superclass และ Subclass
มาเขียน code ที่แสดงให้เห็นความสัมพันธ์ระหว่าง superclass และ subclass
java// SUPERCLASS (Parent/Base Class)
public class Vehicle {
private String brand;
private int year;
public Vehicle(String brand, int year) {
this.brand = brand;
this.year = year;
}
public String getBrand() {
return this.brand;
}
public void start() {
System.out.println("Vehicle is starting...");
}
public void stop() {
System.out.println("Vehicle is stopping...");
}
public void displayInfo() {
System.out.printf("Brand: %s | Year: %d\n", brand, year);
}
}
// SUBCLASS 1 (Child Class)
public class Car extends Vehicle {
private int numberOfDoors;
public Car(String brand, int year, int doors) {
super(brand, year); // เรียก superclass constructor
this.numberOfDoors = doors;
}
public int getNumberOfDoors() {
return this.numberOfDoors;
}
public void displayInfo() {
super.displayInfo(); // เรียก superclass method
System.out.println("Doors: " + numberOfDoors);
}
}
// SUBCLASS 2 (Child Class)
public class Motorcycle extends Vehicle {
private boolean hasSidecar;
public Motorcycle(String brand, int year, boolean sidecar) {
super(brand, year); // เรียก superclass constructor
this.hasSidecar = sidecar;
}
public void displayInfo() {
super.displayInfo(); // เรียก superclass method
System.out.println("Has sidecar: " + hasSidecar);
}
}
// ใช้งาน
public class Main {
public static void main(String[] args) {
// Superclass object
System.out.println("=== Superclass ===");
Vehicle vehicle = new Vehicle("Generic", 2024);
vehicle.displayInfo();
vehicle.start();
// Subclass 1 object
System.out.println("\n=== Subclass 1: Car ===");
Car car = new Car("Toyota", 2024, 4);
car.displayInfo();
car.start(); // Inherited from Vehicle
// Subclass 2 object
System.out.println("\n=== Subclass 2: Motorcycle ===");
Motorcycle motorcycle = new Motorcycle("Harley", 2024, true);
motorcycle.displayInfo();
motorcycle.start(); // Inherited from Vehicle
}
}
Output:
text=== Superclass ===
Brand: Generic | Year: 2024
Vehicle is starting...
=== Subclass 1: Car ===
Brand: Toyota | Year: 2024
Doors: 4
Vehicle is starting...
=== Subclass 2: Motorcycle ===
Brand: Harley | Year: 2024
Has sidecar: true
Vehicle is starting...
คำอธิบาย:
Vehicleคือ superclass – เก็บความสามารถที่เหมือนกันCarและMotorcycleคือ subclass – สืบทอดจาก Vehicle- Subclass สามารถใช้ methods (
start(),stop()) จาก superclass ได้ super.displayInfo()เรียก superclass method ก่อน แล้ว subclass เพิ่มข้อมูลเองต่อ
ลำดับชั้นของ Subclass/Superclass
Single-Level Inheritance
text┌──────────────┐
│ Superclass │
│ (Vehicle) │
└──────────────┘
△
│ extends
│
┌───┴──────────┐
│ │
┌────────┐ ┌────────────┐
│ Car │ │ Motorcycle │
│(Subclass) (Subclass) │
└────────┘ └────────────┘
Multi-Level Inheritance
text┌──────────────┐
│ Vehicle │ ← Superclass level 1
│ (Superclass) │
└──────────────┘
△
│ extends
│
┌───────────┐
│ Car │ ← Superclass level 2 (for SportsCar)
│(Subclass) │ Subclass level 1 (for Vehicle)
└───────────┘
△
│ extends
│
┌────────────┐
│ SportsCar │ ← Subclass level 2
│ (Subclass) │
└────────────┘
ตัวอย่างที่ 2: Multi-Level Subclass/Superclass
java// LEVEL 1: Superclass
public class Animal {
protected String name;
public Animal(String name) {
this.name = name;
}
public void eat() {
System.out.println(name + " is eating");
}
public void sleep() {
System.out.println(name + " is sleeping");
}
}
// LEVEL 2: Subclass of Animal, Superclass of Dog
public class Mammal extends Animal {
protected String furColor;
public Mammal(String name, String furColor) {
super(name);
this.furColor = furColor;
}
public void nurseBaby() {
System.out.println(name + " is nursing baby");
}
public void displayInfo() {
System.out.printf("Name: %s | Fur: %s\n", name, furColor);
}
}
// LEVEL 3: Subclass of Mammal
public class Dog extends Mammal {
private String breed;
public Dog(String name, String furColor, String breed) {
super(name, furColor);
this.breed = breed;
}
public void bark() {
System.out.println(name + " says: Woof!");
}
public void displayInfo() {
super.displayInfo();
System.out.println("Breed: " + breed);
}
}
// ใช้งาน
public class Main {
public static void main(String[] args) {
Dog dog = new Dog("Rex", "Brown", "Husky");
System.out.println("=== Dog Information ===");
dog.displayInfo();
System.out.println("\n=== Dog Actions ===");
dog.eat(); // From Animal (superclass level 1)
dog.sleep(); // From Animal (superclass level 1)
dog.nurseBaby(); // From Mammal (superclass level 2)
dog.bark(); // From Dog (itself)
}
}
Output:
text=== Dog Information ===
Name: Rex | Fur: Brown
Breed: Husky
=== Dog Actions ===
Rex is eating
Rex is sleeping
Rex is nursing baby
Rex says: Woof!
คำอธิบาย:
Dog→Mammal→Animal(hierarchy)Dogเป็น subclass ของMammalMammalเป็น superclass ของDogและ subclass ของAnimalDogสามารถใช้ methods จากทั้งAnimalและMammal
Differences: Superclass vs Subclass
ตารางเปรียบเทียบ
text┌─────────────────┬──────────────────────┬──────────────────────┐
│ │ Superclass │ Subclass │
├─────────────────┼──────────────────────┼──────────────────────┤
│ หน้าที่ │ ให้ความสามารถ │ รับและขยายความสามารถ│
│ Scope │ กว้าง (general) │ แคบ (specific) │
│ Code │ Base functionality │ เพิ่มเติม base code │
│ Methods │ ทั้งหมด public │ บาง methods override │
│ Extends │ ไม่มี extends │ extends superclass │
│ ตัวอย่าง │ Vehicle │ Car, Motorcycle │
└─────────────────┴──────────────────────┴──────────────────────┘
Relationship: “IS-A”
Subclass “IS-A” Superclass
textความสัมพันธ์:
└─ Car IS-A Vehicle
└─ Dog IS-A Animal
└─ Manager IS-A Employee
└─ SportsCar IS-A Car
ทดสอบ:
└─ "Dog is an Animal?" → YES ✓
└─ "Car is a Vehicle?" → YES ✓
└─ "Engine is a Car?" → NO ✗ (ไม่ควรใช้ inheritance)
ตัวอย่างที่ 3: Real-World Scenario
java// SUPERCLASS
public class Shape {
protected String color;
public Shape(String color) {
this.color = color;
}
public String getColor() {
return this.color;
}
public void displayColor() {
System.out.println("Color: " + color);
}
}
// SUBCLASS 1
public class Rectangle extends Shape {
private double width;
private double height;
public Rectangle(String color, double width, double height) {
super(color);
this.width = width;
this.height = height;
}
public double getArea() {
return width * height;
}
public void displayInfo() {
displayColor(); // From superclass
System.out.printf("Rectangle: %.2f x %.2f = %.2f\n",
width, height, getArea());
}
}
// SUBCLASS 2
public class Circle extends Shape {
private double radius;
public Circle(String color, double radius) {
super(color);
this.radius = radius;
}
public double getArea() {
return Math.PI * radius * radius;
}
public void displayInfo() {
displayColor(); // From superclass
System.out.printf("Circle: radius=%.2f, area=%.2f\n",
radius, getArea());
}
}
// SUBCLASS 3: Multi-level
public class Cube extends Rectangle {
private double depth;
public Cube(String color, double side, double depth) {
super(color, side, side);
this.depth = depth;
}
public double getVolume() {
return getArea() * depth;
}
public void displayInfo() {
super.displayInfo();
System.out.printf("Cube: volume=%.2f\n", getVolume());
}
}
// ใช้งาน
public class Main {
public static void main(String[] args) {
Rectangle rect = new Rectangle("Red", 5, 10);
rect.displayInfo();
System.out.println();
Circle circle = new Circle("Blue", 7);
circle.displayInfo();
System.out.println();
Cube cube = new Cube("Green", 3, 3);
cube.displayInfo();
}
}
Output:
textColor: Red
Rectangle: 5.00 x 10.00 = 50.00
Color: Blue
Circle: radius=7.00, area=153.94
Color: Green
Rectangle: 3.00 x 3.00 = 9.00
Cube: volume=27.00
คำอธิบาย:
Shapeเป็น superclass ของRectangleและCircleRectangleเป็น superclass ของCube- ทั้ง subclass สามารถใช้
displayColor()จาก superclass ได้ Cubeสามารถใช้getArea()จากRectangle
ข้อควรระวัง: Superclass vs Subclass
1. Private Members ไม่ Inherit
javapublic class Parent {
private String privateData; // ← ไม่สามารถ access จาก child
protected String protectedData; // ← สามารถ access จาก child
}
public class Child extends Parent {
public void test() {
// ❌ Cannot access privateData
// System.out.println(privateData);
// ✓ Can access protectedData
System.out.println(protectedData);
}
}
2. Constructor ไม่ Inherit (แต่ต้องเรียก super())
javapublic class Parent {
public Parent(String name) {
System.out.println("Parent constructor");
}
}
public class Child extends Parent {
public Child(String name) {
super(name); // ← ต้องเรียก parent constructor
}
}
3. Static Members ไม่ Override (แต่ Inherit)
javapublic class Parent {
public static void staticMethod() {
System.out.println("Parent static");
}
}
public class Child extends Parent {
public static void staticMethod() {
System.out.println("Child static"); // ← Shadowing, not overriding
}
}
// ใช้งาน
Parent.staticMethod(); // "Parent static"
Child.staticMethod(); // "Child static"
Parent obj = new Child();
obj.staticMethod(); // "Parent static" (called via Parent reference)
Hierarchy Best Practices
1. Single Superclass
java// ✓ ดี: ชัดเจน
public class Dog extends Animal {
// Dog extends only Animal
}
// ❌ Java ไม่อนุญาต: Multiple inheritance
// public class Dog extends Animal, Mammal {
2. Appropriate Naming
java// ✓ ชื่อชัดเจน
class Vehicle {} // Superclass
class Car extends Vehicle {} // Subclass
class SportsCar extends Car {} // Sub-subclass
// ❌ ชื่อสับสน
class X {}
class Y extends X {}
class Z extends Y {}
3. ไม่ควร Extend เกิน 3-4 Levels
java// ✓ ดีพอ
A → B → C
// ⚠️ ซับซ้อนเกินไป
A → B → C → D → E → F
Type Compatibility
Subclass object สามารถ assign ให้ Superclass reference ได้
javaVehicle vehicle = new Car("Toyota", 2024, 4);
// ✓ ถูกต้อง: Subclass object → Superclass reference
Car car = new Vehicle();
// ❌ ผิด: Superclass object → Subclass reference
ตัวอย่างที่ 4: Type Compatibility
javapublic class Main {
public static void main(String[] args) {
// Car object
Car car = new Car("Toyota", 2024, 4);
// ✓ Assign to Vehicle reference (superclass)
Vehicle vehicle = car;
vehicle.displayInfo(); // ใช้ได้
vehicle.start(); // ใช้ได้
// ❌ ไม่สามารถ access Car-specific method ผ่าน Vehicle reference
// vehicle.getNumberOfDoors(); // ERROR!
// ✓ ต้อง cast กลับเป็น Car
Car carAgain = (Car) vehicle;
System.out.println("Doors: " + carAgain.getNumberOfDoors());
}
}
public class Vehicle {
private String brand;
private int year;
public Vehicle(String brand, int year) {
this.brand = brand;
this.year = year;
}
public void displayInfo() {
System.out.printf("Brand: %s | Year: %d\n", brand, year);
}
public void start() {
System.out.println("Vehicle is starting");
}
}
public class Car extends Vehicle {
private int numberOfDoors;
public Car(String brand, int year, int doors) {
super(brand, year);
this.numberOfDoors = doors;
}
public int getNumberOfDoors() {
return numberOfDoors;
}
}
Output:
textBrand: Toyota | Year: 2024
Vehicle is starting
Doors: 4
คำอธิบาย:
Vehicle vehicle = car;– assign Car object ให้ Vehicle reference- ผ่าน
vehiclereference สามารถใช้ Vehicle methods ได้ - ต้อง cast กลับเป็น
Carเพื่อเข้าถึง Car-specific methods
สรุป
Superclass และ Subclass เป็นศัพท์พื้นฐานในการเข้าใจ inheritance ที่ superclass คือ class ที่ให้ความสามารถ (เหมือนพ่อแม่) ในขณะที่ subclass คือ class ที่รับความสามารถนั้น (เหมือนลูก)
ความเข้าใจที่ลึกซึ้งเกี่ยวกับความสัมพันธ์นี้ช่วยให้เราออกแบบระบบ class ที่เหมาะสม เรา ต้องสร้าง superclass ที่มีคุณลักษณะร่วม ของหลาย objects และให้ subclass เพิ่มเติมหรือปรับแต่ง functionality ให้เหมาะสมกับตัวเอง
สิ่งสำคัญที่ต้องจำคือ ความสัมพันธ์ IS-A ต้องเป็นจริง เช่น “Dog IS-A Animal” และ ลำดับชั้นไม่ควรลึกเกินไป เพราะมันจะทำให้ code ซับซ้อนและยากต่อการดูแล เมื่อ subclass หรือ superclass ถูกออกแบบได้ดี inheritance จะกลายเป็นเครื่องมือที่ทรงพลังในการสร้าง code ที่มีโครงสร้างและสามารถนำกลับมาใช้ได้
