เชี่ยวชาญการสืบทอดใน Java: วิธีการทำงานของคีย์เวิร์ด extends (คู่มือฉบับสมบูรณ์)

目次

1. Introduction

Java เป็นภาษาการเขียนโปรแกรมที่ได้รับการใช้อย่างกว้างขวางในหลายสาขา ตั้งแต่ระบบองค์กรจนถึงเว็บแอปพลิเคชันและการพัฒนา Android. ในคุณสมบัติมากมายของมัน “การสืบทอด (inheritance)” เป็นหนึ่งในแนวคิดที่สำคัญที่สุดเมื่อเรียนรู้การเขียนโปรแกรมเชิงวัตถุ.

โดยการใช้การสืบทอด คลาสใหม่ (subclass/child class) สามารถรับฟังก์ชันการทำงานของคลาสที่มีอยู่แล้ว (superclass/parent class) ได้ ซึ่งช่วยลดการทำซ้ำของโค้ดและทำให้โปรแกรมง่ายต่อการขยายและบำรุงรักษา. ใน Java การสืบทอดถูกนำมาใช้ผ่านคีย์เวิร์ด extends.

ในบทความนี้ เราจะอธิบายบทบาทของคีย์เวิร์ด extends ใน Java อย่างชัดเจน รวมถึงการใช้งานพื้นฐาน การประยุกต์ใช้ในเชิงปฏิบัติ และคำถามที่พบบ่อย. คู่มือนี้เป็นประโยชน์ไม่เพียงแต่สำหรับผู้เริ่มต้นใน Java แต่ยังสำหรับผู้ที่ต้องการทบทวนการสืบทอด. เมื่ออ่านจบคุณจะเข้าใจข้อดีและข้อเสียของการสืบทอดอย่างเต็มที่ รวมถึงข้อควรพิจารณาในการออกแบบที่สำคัญ.

มาดูรายละเอียดของ “การสืบทอดใน Java คืออะไร?” กันเถอะ.

2. What Is Java Inheritance?

การสืบทอดใน Java คือกลไกที่คลาสหนึ่ง (superclass/parent class) ส่งต่อคุณลักษณะและฟังก์ชันการทำงานให้กับคลาสอีกคลาสหนึ่ง (subclass/child class). ด้วยการสืบทอด ฟิลด์ (ตัวแปร) และเมธอด (ฟังก์ชัน) ที่กำหนดในคลาสพาเรนท์สามารถนำกลับมาใช้ใหม่ในคลาสชิลด์ได้.

กลไกนี้ทำให้การจัดระเบียบและการจัดการโค้ดง่ายขึ้น, รวมศูนย์กระบวนการที่ใช้ร่วมกัน, และขยายหรือปรับเปลี่ยนฟังก์ชันการทำงานได้อย่างยืดหยุ่น. การสืบทอดเป็นหนึ่งในสามเสาหลักของการเขียนโปรแกรมเชิงวัตถุ (OOP) ร่วมกับการห่อหุ้ม (encapsulation) และพหุรูป (polymorphism).

About the “is-a” Relationship

ตัวอย่างที่พบบ่อยของการสืบทอดคือ “ความสัมพันธ์แบบ is-a”. ตัวอย่างเช่น “สุนัขเป็นสัตว์”. นั่นหมายความว่า คลาส Dog สืบทอดจากคลาส Animal. สุนัขสามารถรับคุณลักษณะและพฤติกรรมของสัตว์ได้พร้อมกับเพิ่มฟีเจอร์เฉพาะของตนเอง.

class Animal {
    void eat() {
        System.out.println("食べる");
    }
}

class Dog extends Animal {
    void bark() {
        System.out.println("ワンワン");
    }
}

ในตัวอย่างนี้ คลาส Dog สืบทอดจากคลาส Animal. อินสแตนซ์ของ Dog สามารถใช้เมธอด bark และเมธอด eat ที่สืบทอดมาจาก Animal ได้.

What Happens When You Use Inheritance?

  • คุณสามารถรวมตรรกะและข้อมูลที่ใช้ร่วมกันไว้ในคลาสพาเรนท์, ลดความจำเป็นในการเขียนโค้ดเดียวกันซ้ำ ๆ ในแต่ละซับคลาส.
  • แต่ละซับคลาสสามารถเพิ่มพฤติกรรมเฉพาะของตนเองหรือทำการโอเวอร์ไรด์เมธอดของคลาสพาเรนท์ได้.

การใช้การสืบทอดช่วยจัดโครงสร้างโปรแกรมและทำให้การเพิ่มฟีเจอร์และการบำรุงรักษาง่ายขึ้น. อย่างไรก็ตาม การสืบทอดไม่ได้เป็นตัวเลือกที่ดีที่สุดเสมอไป, และจึงสำคัญที่จะประเมินอย่างรอบคอบว่ามี “ความสัมพันธ์แบบ is-a” ที่แท้จริงหรือไม่ในขั้นตอนการออกแบบ.

3. How the extends Keyword Works

คีย์เวิร์ด extends ใน Java ระบุการสืบทอดของคลาสอย่างชัดเจน. เมื่อคลาสชิลด์สืบทอดฟังก์ชันการทำงานของคลาสพาเรนท์, ไวยากรณ์ extends ParentClassName จะถูกใช้ในคำประกาศคลาส. สิ่งนี้ทำให้คลาสชิลด์สามารถใช้สมาชิกสาธารณะทั้งหมด (ฟิลด์และเมธอด) ของคลาสพาเรนท์ได้โดยตรง.

Basic Syntax

class ParentClass {
    // Fields and methods of the parent class
}

class ChildClass extends ParentClass {
    // Fields and methods unique to the child class
}

ตัวอย่างเช่น การใช้คลาส Animal และ Dog ที่กล่าวถึงก่อนหน้า เราจะได้:

class Animal {
    void eat() {
        System.out.println("食べる");
    }
}

class Dog extends Animal {
    void bark() {
        System.out.println("ワンワン");
    }
}

โดยการเขียน Dog extends Animal, คลาส Dog จะสืบทอดจากคลาส Animal และสามารถใช้เมธอด eat ได้.

Using Parent Class Members

ด้วยการสืบทอด อินสแตนซ์ของคลาสชิลด์สามารถเข้าถึงเมธอดและฟิลด์ของคลาสพาเรนท์ (ตราบใดที่ตัวแก้ไขการเข้าถึงอนุญาต) :

Dog dog = new Dog();
dog.eat();   // Calls the parent class method
dog.bark();  // Calls the child class method

หมายเหตุสำคัญ

  • Java อนุญาตให้สืบทอดจากคลาสได้เพียงคลาสเดียว (การสืบทอดแบบเดี่ยว) คุณไม่สามารถระบุหลายคลาสหลังจาก extends ได้ .
  • หากต้องการป้องกันการสืบทอด คุณสามารถใช้ตัวแก้ไข final กับคลาสได้.

เคล็ดลับการพัฒนาปฏิบัติ

การใช้ extends อย่างเหมาะสมช่วยให้คุณรวมฟังก์ชันการทำงานที่ใช้ร่วมกันไว้ในคลาสพาเรนต์และขยายหรือปรับแต่งพฤติกรรมในซับคลาส นอกจากนี้ยังเป็นประโยชน์เมื่อคุณต้องการเพิ่มฟีเจอร์ใหม่โดยไม่ต้องแก้ไขโค้ดที่มีอยู่.

4. การเขียนทับเมธอดและคีย์เวิร์ด super

เมื่อใช้การสืบทอด มีบางกรณีที่คุณต้องการเปลี่ยนแปลงพฤติกรรมของเมธอดที่กำหนดในคลาสพาเรนต์ ซึ่งเรียกว่า “การเขียนทับเมธอด” ใน Java การเขียนทับทำโดยการกำหนดเมธอดในคลาสลูกที่มีชื่อและรายการพารามิเตอร์เดียวกับเมธอดในคลาสพาเรนต์.

การเขียนทับเมธอด

เมื่อเขียนทับเมธอด มักจะเพิ่มคำอธิบาย @Override ซึ่งช่วยให้คอมไพเลอร์ตรวจจับข้อผิดพลาดโดยไม่ได้ตั้งใจ เช่น ชื่อเมธอดหรือลายเซ็นที่ไม่ถูกต้อง.

class Animal {
    void eat() {
        System.out.println("食べる");
    }
}

class Dog extends Animal {
    @Override
    void eat() {
        System.out.println("ドッグフードを食べる");
    }
}

ในตัวอย่างนี้ คลาส Dog เขียนทับเมธอด eat เมื่อเรียก eat บนอินสแตนซ์ของ Dog ผลลัพธ์จะเป็น “ドッグフードを食べる”.

Dog dog = new Dog();
dog.eat(); // Displays: ドッグフードを食べる

การใช้คีย์เวิร์ด super

หากคุณต้องการเรียกเมธอดดั้งเดิมของคลาสพาเรนต์ภายในเมธอดที่เขียนทับ ให้ใช้คีย์เวิร์ด super.

class Dog extends Animal {
    @Override
    void eat() {
        super.eat(); // Calls the parent class’s eat()
        System.out.println("ドッグフードも食べる");
    }
}

นี้จะเรียกเมธอด eat ของคลาสพาเรนต์ก่อน แล้วจึงเพิ่มพฤติกรรมของซับคลาส.

ตัวสร้างและ super

หากคลาสพาเรนต์มีตัวสร้างที่รับพารามิเตอร์ คลาสลูกต้องเรียกอย่างชัดเจนโดยใช้ super(arguments) เป็นบรรทัดแรกของตัวสร้างของมัน.

class Animal {
    Animal(String name) {
        System.out.println("Animal: " + name);
    }
}

class Dog extends Animal {
    Dog(String name) {
        super(name);
        System.out.println("Dog: " + name);
    }
}

สรุป

  • การเขียนทับหมายถึงการกำหนดเมธอดของคลาสพาเรนต์ใหม่ในคลาสลูก.
  • แนะนำให้ใช้คำอธิบาย @Override.
  • ใช้ super เมื่อคุณต้องการใช้การทำงานของเมธอดในคลาสพาเรนต์ซ้ำ.
  • super ยังใช้เมื่อต้องเรียกตัวสร้างของคลาสพาเรนต์.

5. ข้อดีและข้อเสียของการสืบทอด

การสืบทอดใน Java นำมาซึ่งประโยชน์หลายประการต่อการออกแบบและพัฒนาโปรแกรม อย่างไรก็ตาม การใช้ที่ไม่ถูกต้องอาจทำให้เกิดปัญหาร้ายแรง ด้านล่างนี้เราจะอธิบายข้อดีและข้อเสียอย่างละเอียด.

ข้อดีของการสืบทอด

  1. เพิ่มการนำโค้ดกลับมาใช้ใหม่ การกำหนดตรรกะและข้อมูลที่ใช้ร่วมกันในคลาสพาเรนต์ทำให้ไม่ต้องทำซ้ำโค้ดเดียวกันในแต่ละซับคลาส ซึ่งช่วยลดการทำซ้ำและปรับปรุงการบำรุงรักษาและความอ่านง่าย.
  2. การขยายที่ง่ายขึ้น เมื่อจำเป็นต้องมีฟังก์ชันใหม่ คุณสามารถสร้างซับคลาสใหม่จากคลาสพาเรนต์โดยไม่ต้องแก้ไขโค้ดที่มีอยู่ ซึ่งช่วยลดผลกระทบจากการเปลี่ยนแปลงและลดโอกาสเกิดบั๊ก.
  3. สนับสนุนพหุรูป การสืบทอดทำให้ “ตัวแปรของคลาสพาเรนต์สามารถอ้างอิงถึงอินสแตนซ์ของคลาสลูก” ซึ่งทำให้การออกแบบมีความยืดหยุ่นโดยใช้อินเทอร์เฟซทั่วไปและพฤติกรรมพหุรูป.

ข้อเสียของการสืบทอด

  1. ลำดับชั้นลึกทำให้การออกแบบซับซ้อน หากโซ่การสืบทอดเติบโตลึกเกินไป จะทำให้ยากต่อการเข้าใจว่าพฤติกรรมถูกกำหนดที่ใด ทำให้การบำรุงรักษายากขึ้น
  2. การเปลี่ยนแปลงในคลาสพ่อแม่ส่งผลต่อทุกคลาสลูก การแก้ไขพฤติกรรมของคลาสพ่อแม่อาจทำให้เกิดปัญหาโดยไม่ตั้งใจในทุกคลาสลูก คลาสพ่อแม่ต้องการการออกแบบและการอัปเดตอย่างระมัดระวัง
  3. อาจลดความยืดหยุ่นของการออกแบบ การใช้การสืบทอดมากเกินไปทำให้คลาสเชื่อมโยงกันอย่างแน่นหนา ทำให้การเปลี่ยนแปลงในอนาคตทำได้ยาก ในบางกรณี ความสัมพันธ์ “has-a” ที่ใช้การประกอบ (composition) จะยืดหยุ่นกว่าการสืบทอด “is-a”

สรุป

การสืบทอดเป็นเครื่องมือที่ทรงพลัง แต่การพึ่งพามันสำหรับทุกอย่างอาจทำให้เกิดปัญหาในระยะยาว ควรตรวจสอบว่ามีความสัมพันธ์ “is-a” ที่แท้จริงหรือไม่ และใช้การสืบทอดเฉพาะเมื่อเหมาะสม

6. ความแตกต่างระหว่างการสืบทอดและอินเทอร์เฟซ

Java มีกลไกสำคัญสองอย่างสำหรับการขยายและจัดระเบียบฟังก์ชันการทำงาน: การสืบทอดคลาส (extends) และอินเทอร์เฟซ (implements) ทั้งสองสนับสนุนการใช้โค้ดซ้ำและการออกแบบที่ยืดหยุ่น แต่โครงสร้างและการใช้งานที่ตั้งใจแตกต่างกันอย่างมาก ด้านล่างนี้เราจะอธิบายความแตกต่างและวิธีเลือกใช้ระหว่างสองแบบนี้

ความแตกต่างระหว่าง extends และ implements

  • extends (การสืบทอด)
  • คุณสามารถสืบทอดจากคลาสได้เพียงคลาสเดียว (single inheritance)
  • ฟิลด์และเมธอดที่ทำงานเต็มรูปแบบจากคลาสพ่อแม่สามารถใช้โดยตรงในคลาสลูก
  • แสดงถึงความสัมพันธ์ “is-a” (เช่น Dog เป็น Animal)
  • implements (การทำอินเทอร์เฟซ)
  • สามารถทำอินเทอร์เฟซหลายตัวพร้อมกันได้
  • อินเทอร์เฟซมีเพียงการประกาศเมธอด (แม้ว่าจะมีเมธอด default ตั้งแต่ Java 8 เป็นต้นไป)
  • แสดงถึงความสัมพันธ์ “can-do” (เช่น Dog สามารถเห่า, Dog สามารถเดิน)

ตัวอย่างการใช้อินเทอร์เฟซ

interface Walkable {
    void walk();
}

interface Barkable {
    void bark();
}

class Dog implements Walkable, Barkable {
    public void walk() {
        System.out.println("歩く");
    }
    public void bark() {
        System.out.println("ワンワン");
    }
}

ในตัวอย่างนี้ คลาส Dog ทำอินเทอร์เฟซสองตัวคือ Walkable และ Barkable เพื่อให้พฤติกรรมคล้ายกับการสืบทอดหลายรูปแบบ

ทำไมต้องมีอินเทอร์เฟซ

Java ห้ามการสืบทอดหลายคลาสพร้อมกัน เพราะอาจทำให้เกิดความขัดแย้งเมื่อคลาสพ่อแม่กำหนดเมธอดหรือฟิลด์เดียวกัน อินเทอร์เฟซแก้ปัญหานี้โดยให้คลาสสามารถรับ “ประเภท” หลายประเภทได้โดยไม่ต้องสืบทอดการทำงานที่ขัดแย้งกัน

วิธีใช้ให้ถูกต้อง

  • ใช้ extends เมื่อมีความสัมพันธ์ “is-a” ชัดเจนระหว่างคลาส
  • ใช้ implements เมื่อต้องการกำหนดสัญญาพฤติกรรมร่วมกันให้หลายคลาส

ตัวอย่าง:

  • “Dog เป็น Animal” → Dog extends Animal
  • “Dog สามารถเดินและสามารถเห่า” → Dog implements Walkable, Barkable

สรุป

  • คลาสหนึ่งสามารถสืบทอดจากคลาสพ่อแม่ได้เพียงหนึ่งคลาส แต่สามารถทำอินเทอร์เฟซหลายตัวได้
  • การเลือกใช้การสืบทอดหรืออินเทอร์เฟซตามเจตนาการออกแบบจะทำให้โค้ดสะอาด ยืดหยุ่น และบำรุงรักษาได้ง่าย

7. แนวทางปฏิบัติที่ดีที่สุดสำหรับการใช้การสืบทอด

การสืบทอดใน Java มีพลังมาก แต่การใช้ไม่ถูกต้องอาจทำให้โปรแกรมแข็งกระด้างและบำรุงรักษายาก ด้านล่างนี้เป็นแนวทางปฏิบัติและคำแนะนำสำหรับการใช้การสืบทอดอย่างปลอดภัยและมีประสิทธิภาพ

เมื่อควรใช้การสืบทอด — และเมื่อควรหลีกเลี่ยง

  • ใช้การสืบทอดเมื่อ:
  • มีความสัมพันธ์ “is-a” ชัดเจน (เช่น Dog เป็น Animal)
  • ต้องการใช้ฟังก์ชันของคลาสพ่อแม่และขยายมัน
  • ต้องการกำจัดโค้ดซ้ำและรวมตรรกะที่ใช้ร่วมกันไว้ในที่เดียว
  • หลีกเลี่ยงการสืบทอดเมื่อ:
  • ใช้เพียงเพื่อการใช้โค้ดซ้ำ (มักทำให้การออกแบบคลาสไม่เป็นธรรมชาติ)
  • ความสัมพันธ์ “has-a” เหมาะสมกว่า — ในกรณีนั้นควรพิจารณาการประกอบ (composition)

การเลือกใช้ระหว่างการสืบทอดและการประกอบ

  • การสืบทอด (extends): ความสัมพันธ์แบบ is-a
  • ตัวอย่าง: Dog extends Animal
  • มีประโยชน์เมื่อคลาสย่อยจริง ๆ แทนประเภทของคลาสพาเรนท์
  • การรวม (Composition) (ความสัมพันธ์แบบ has-a)
  • ตัวอย่าง: รถยนต์ (Car) มีเครื่องยนต์ (Engine)
  • ใช้ตัวอย่างของคลาสอื่นภายในเพื่อเพิ่มฟังก์ชันการทำงาน
  • ยืดหยุ่นมากกว่าและปรับเปลี่ยนได้ง่ายต่อการเปลี่ยนแปลงในอนาคต

แนวทางการออกแบบเพื่อป้องกันการใช้การสืบทอดอย่างไม่เหมาะสม

  • อย่าสร้างลำดับชั้นการสืบทอดที่ลึกเกินไป (ควรจำกัดไว้ที่ 3 ระดับหรือไม่เกิน)
  • หากมีคลาสย่อยหลายคลาสสืบทอดจากพาเรนท์เดียวกัน ให้ประเมินใหม่ว่าหน้าที่ของพาเรนท์นั้นเหมาะสมหรือไม่
  • พิจารณาความเสี่ยงที่การเปลี่ยนแปลงในคลาสพาเรนท์จะส่งผลต่อคลาสย่อยทั้งหมดเสมอ
  • ก่อนนำการสืบทอดไปใช้ ให้พิจารณาทางเลือกอื่นเช่น อินเทอร์เฟซและการรวม

การจำกัดการสืบทอดด้วยตัวแก้ไข final

  • การใส่ final ให้กับคลาสจะทำให้คลาสนั้นไม่สามารถสืบทอดต่อได้
  • การใส่ final ให้กับเมธอดจะทำให้เมธอดนั้นไม่สามารถถูกโอเวอร์ไรด์โดยคลาสย่อยได้
    final class Utility {
        // This class cannot be inherited
    }
    
    class Base {
        final void show() {
            System.out.println("オーバーライド禁止");
        }
    }
    

การเสริมเอกสารและคอมเมนต์

  • การบันทึกความสัมพันธ์การสืบทอดและเจตนาการออกแบบคลาสใน Javadoc หรือคอมเมนต์ช่วยให้การบำรุงรักษาในอนาคตทำได้ง่ายขึ้นมาก

สรุป

การสืบทอดเป็นเครื่องมือที่สะดวก แต่ต้องใช้ด้วยเจตนาที่ชัดเจน เสมอถามว่า “คลาสนี้เป็นประเภทของพาเรนท์จริงหรือไม่?” หากไม่แน่ใจ ให้พิจารณาการรวมหรืออินเทอร์เฟซเป็นทางเลือก

8. สรุป

จนถึงจุดนี้ เราได้อธิบายการสืบทอดใน Java และคีย์เวิร์ด extends อย่างละเอียด ตั้งแต่พื้นฐานจนถึงการใช้งานจริง ด้านล่างเป็นการสรุปประเด็นสำคัญที่กล่าวถึงในบทความนี้

  • การสืบทอดใน Java ทำให้คลาสย่อยรับข้อมูลและฟังก์ชันของคลาสพาเรนท์ได้ ช่วยให้การออกแบบโปรแกรมมีประสิทธิภาพและนำกลับมาใช้ใหม่ได้
  • คีย์เวิร์ด extends ชี้แจงความสัมพันธ์ระหว่างพาเรนท์และคลาสลูก (ความสัมพันธ์แบบ “is-a”)
  • การโอเวอร์ไรด์เมธอดและคีย์เวิร์ด super ทำให้สามารถขยายหรือปรับแต่งพฤติกรรมที่สืบทอดได้
  • การสืบทอดมีข้อได้เปรียบหลายอย่าง เช่น การใช้โค้ดซ้ำ, ความสามารถในการขยาย, และการสนับสนุนพหุรูปแบบ (polymorphism) แต่ก็มีข้อเสียเช่น ลำดับชั้นที่ลึกหรือซับซ้อนและการเปลี่ยนแปลงที่มีผลกว้างขวาง
  • การเข้าใจความแตกต่างระหว่างการสืบทอด, อินเทอร์เฟซ, และการรวมเป็นสิ่งสำคัญในการเลือกแนวทางการออกแบบที่เหมาะสม
  • อย่าใช้การสืบทอดเกินความจำเป็น; ควรชัดเจนเกี่ยวกับเจตนาการออกแบบและเหตุผล

การสืบทอดเป็นหนึ่งในแนวคิดหลักของการเขียนโปรแกรมเชิงวัตถุใน Java การเข้าใจกฎและแนวปฏิบัติที่ดีที่สุดจะทำให้คุณสามารถนำไปใช้ได้อย่างมีประสิทธิภาพในโครงการจริง

9. คำถามที่พบบ่อย (FAQ)

Q1: สิ่งใดเกิดขึ้นกับคอนสตรัคเตอร์ของคลาสพาเรนท์เมื่อมีการสืบทอดคลาสใน Java?
A1: หากคลาสพาเรนท์มีคอนสตรัคเตอร์ที่ไม่มีอาร์กิวเมนต์ (default) จะถูกเรียกโดยอัตโนมัติจากคอนสตรัคเตอร์ของคลาสลูก หากคลาสพาเรนท์มีคอนสตรัคเตอร์ที่ต้องการพารามิเตอร์เท่านั้น คลาสลูกต้องเรียกอย่างชัดเจนโดยใช้ super(arguments) ที่จุดเริ่มต้นของคอนสตรัคเตอร์ของมัน

Q2: Java สามารถทำการสืบทอดหลายคลาสได้หรือไม่?
A2: ไม่ได้ Java ไม่รองรับการสืบทอดหลายคลาส คลาสหนึ่งสามารถสืบทอดจากพาเรนท์ได้เพียงคลาสเดียวโดยใช้ extends อย่างไรก็ตามคลาสหนึ่งสามารถทำการ implement อินเทอร์เฟซหลายตัวได้โดยใช้ implements

Q3: ความแตกต่างระหว่างการสืบทอดและการรวมคืออะไร?
A3: การสืบทอดแสดงถึง “ความสัมพันธ์แบบ is-a” ซึ่งคลาสลูกใช้ฟังก์ชันและข้อมูลของคลาสพาเรนท์ ส่วนการรวมแสดงถึง “ความสัมพันธ์แบบ has-a” ซึ่งคลาสหนึ่งมีอินสแตนซ์ของคลาสอื่น การรวมมักให้ความยืดหยุ่นมากกว่าและเป็นทางเลือกที่ดีกว่าในหลายกรณีที่ต้องการการแยกส่วน (loose coupling) หรือการขยายในอนาคต

Q4: ตัวแก้ไข final จำกัดการสืบทอดและการเขียนทับหรือไม่?
A4: ใช่. หากคลาสถูกทำเครื่องหมายว่า final จะไม่สามารถสืบทอดได้ หากเมธอดถูกทำเครื่องหมายว่า final จะไม่สามารถเขียนทับในคลาสย่อยได้ สิ่งนี้มีประโยชน์เพื่อให้พฤติกรรมคงที่หรือเพื่อเหตุผลด้านความปลอดภัย

Q5: จะเกิดอะไรขึ้นหากคลาสพาเรนท์และคลาสลูกกำหนดฟิลด์หรือเมธอดที่มีชื่อเดียวกัน?
A5: หากฟิลด์ที่มีชื่อเดียวกันถูกกำหนดในทั้งสองคลาส ฟิลด์ในคลาสลูกจะซ่อนฟิลด์ในคลาสพาเรนท์ (shadowing) เมธอดทำงานต่างกัน: หากลายเซ็นตรงกัน เมธอดของคลาสลูกจะเขียนทับเมธอดของคลาสพาเรนท์ โปรดทราบว่าฟิลด์ไม่สามารถเขียนทับได้—สามารถซ่อนได้เท่านั้น

Q6: จะเกิดอะไรขึ้นหากความลึกของการสืบทอดมากเกินไป?
A6: โครงสร้างการสืบทอดที่ลึกทำให้โค้ดยากต่อการเข้าใจและบำรุงรักษา การติดตามว่าตรรกะถูกกำหนดที่ไหนก็ยากขึ้น เพื่อการออกแบบที่บำรุงรักษาได้ ควรพยายามให้ความลึกของการสืบทอดตื้นและแยกบทบาทให้ชัดเจน

Q7: ความแตกต่างระหว่างการเขียนทับและการโอเวอร์โหลดคืออะไร?
A7: การเขียนทับ (overriding) คือการกำหนดเมธอดใหม่จากคลาสพาเรนท์ในคลาสลูก ส่วนการโอเวอร์โหลด (overloading) คือการกำหนดเมธอดหลาย ๆ ตัวในคลาสเดียวกันที่มีชื่อเดียวกันแต่พารามิเตอร์ต่างชนิดหรือจำนวน

Q8: ควรใช้คลาสเชิงนามธรรมและอินเทอร์เฟซอย่างไรให้แตกต่างกัน?
A8: คลาสเชิงนามธรรมใช้เมื่อคุณต้องการให้มีการนำรหัสหรือฟิลด์ที่ใช้ร่วมกันระหว่างคลาสที่เกี่ยวข้อง อินเทอร์เฟซใช้เมื่อคุณต้องการกำหนดสัญญาพฤติกรรมที่หลายคลาสสามารถทำตามได้ ใช้คลาสเชิงนามธรรมสำหรับโค้ดที่ใช้ร่วมกันและใช้อินเทอร์เฟซเมื่อแสดงหลายประเภทหรือเมื่อต้องการ “ความสามารถ” หลายอย่าง