Inheritance

25 August 2016

ในบทนี้ คุณจะได้เรียนรู้เกี่ยวกับ Inheritance (การสืบทอด) ในภาษา Java ซึ่งเป็นคุณสมบัติที่สำคัญในการเขียนโปรแกรมเชิงวัตถุ

Inheritance คืออะไร

Inheritance เป็นคุณสมบัติในการเขียนโปรแกรมเชิงวัตถุที่เรียกว่าคุณสมบัติการสืบทอด โดยที่คลาสสามารถสืบทอดสมาชิกของมันจากคลาสหลัก (super class) ไปยังคลาสย่อย (delivered class) โดยการสืบทอดในภาษา Java นั้นสมาชิกทั้งหมดจะถูกสืบทอดไปยังคลาสย่อย ยกเว้นสมาชิกที่มีระดับการเข้าถึงเป็น private และ constructor ของมัน

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

class DeliveredClass extends SuperClass {
    ...
}

ในการสืบทอดนั้นจะใช้คำสั่ง extends โดย SuperClass นั้นเป็นคลาสหลักที่จะสืบทอดไปยัง DeliveredClass

สร้าง Inheritance คลาส

ต่อไปมาดูตัวอย่างของการสืยทอดคลาสในภาษา Java เราจะสร้างคลาส Person เวอร์ชันใหม่ขึ้นมา

class Person {
    String name;
    int age;

    public Person () {
    }

    public Person (String name, int age) {
        this.name = name;
        this.age = age;
    }

    public void introduce () {
        System.out.println("My name is " + name);
    }
}

ในตัวอย่างเป็นคลาส Person ของเรา เราจะใช้คลาสนี้ในการสืบทอดคุณสมบัติให้กับคลาสอื่น ซึ่งหมายความว่าคลาสนี้จะเป็น super class

class Artist extends Person {
    String genre;

    public Artist (String name, int age){
        this.name = name;
        this.age = age;
    }

    public void playMusic () {
        System.out.println(name + " is playing " + genre + " music.");
    }
}

class Athlete extends Person {
    String sport;

    public Athlete (String name, int age){
        this.name = name;
        this.age = age;
    }

    public void playSport () {
        System.out.println(name + " is playing " + sport + ".");
    }
}

ต่อมาเราได้สร้าง delivered class ขึ้นมาดังนี้

คลาส Artist เป็นคลาสที่สืบทอดมาจากคลาส Person นั่นหมายความว่าสมาชิกทั้งหมดของ Person ยกเว้น constructor และสมาชิกที่เป็น private จะไม่ถูกสืบทอดมาด้วย และเราได้เพิ่มตัวแปรให้กับคลาสนี้ คือ genre เป็นตัวแปรสำหรับประเภทดนตรีที่เล่น และเมธอด playMusic() เพื่อเล่นดนตรี

ต่อมาเป็นคลาส Athlete การสืบทอดนั้นเป็นเช่นเดียวกันกับคลาส Artist เพราะสืบทอดมาจากคลาสเดียวกัน และเราได้เพิ่มตัวแปรให้กับคลาสนี้ คือ sport เป็นตัวแปรสำหรับกีฬาที่เล่น และเมธอด playSport() เพื่อเล่นกี่ฬานั้น

เรายังสร้าง constructor ให้กับคลาสทั้งสองด้วย เพราะว่า constructor ไม่ได้สืบทอด ต่อมาเป็นตัวอย่างการใช้งาน เราคำโค้ดทั้งหมดมารวมกันและทำการสร้างออบเจ็ค

public class InheritanceExample {
    public static void main (String[] args) {
        Artist art = new Artist("Marcus", 20);
        Athlete ath = new Athlete("Danny", 25);

        art.genre = "Trip Hop";
        ath.sport = "Football";

        art.introduce();
        art.playMusic();

        System.out.println();

        ath.introduce();
        ath.playSport();
    }
}

class Person {
    String name;
    int age;

    public Person () {
    }

    public Person (String name, int age) {
        this.name = name;
        this.age = age;
    }

    public void introduce () {
        System.out.println("My name is " + name);
    }
}

class Artist extends Person {
    String genre;

    public Artist (String name, int age){
        this.name = name;
        this.age = age;
    }

    public void playMusic () {
        System.out.println(name + " is playing " + genre + " music.");
    }
}

class Athlete extends Person {
    String sport;

    public Athlete (String name, int age){
        this.name = name;
        this.age = age;
    }

    public void playSport () {
        System.out.println(name + " is playing " + sport + ".");
    }
}

ในตัวอย่างเราได้สร้างออบเจ็คจากคลาสทั้งสองขึ้นมา และกำหนดค่าคุณสังเกตุว่าในคอนสตรัคเตอร์ของ delivered class ทั้งสองเราได้ใช้คำสั่ง this.name ก็คือตัวแปรที่สืบทอดมาจาก super คลาส และในเมธอด Main คำสั่ง art.introduce() และ ath.introduce() คือเมธอดที่ถูกสืบทอดมาเช่นกัน สังเกตุว่าเราไม่ต้องประกาศอีกในตอนสร้าง delivered class ซึ่งนี่เป็นอีกเหตุผลหนึ่งทำให้เราสามารถนำโค้ดเดิมมาใช้ได้ โดยไม่ต้องเขียนใหม่ทั้งหมด

My name is Marcus
Marcus is playing Trip Hop music.

My name is Danny
Danny is playing Football.

และนี่เป็นผลลัพธ์ของการรันโปรแกรม

Overriding Super Class

ในการสืบทอดจาก super class มายัง delivered class นั้น delivered class ยังสามารถ override การทำงานของเมธอดใน super class ได้ โดยการ override เมธอดในภาษา Java นั้นจะใช้คำสั่ง @Override นำหน้าเมธอดที่ต้องการ

class Artist extends Person {
    String genre;

    public Artist (String name, int age){
        this.name = name;
        this.age = age;
    }

    @Override
    public void introduce () {
        System.out.println("My name is " + name);
        System.out.println("I'm an artist.");
    }

    public void playMusic () {
        System.out.println(name + " is playing " + genre + " music.");
    }
}

class Athlete extends Person {
    String sport;

    public Athlete (String name, int age){
        this.name = name;
        this.age = age;
    }

    @Override
    public void introduce () {
        System.out.println("My name is " + name);
        System.out.println("I'm an athlete.");
    }

    public void playSport () {
        System.out.println(name + " is playing " + sport + ".");
    }
}

จากตัวอย่างเป็นการ override เมธอด introduce() จาก super class เพื่อให้กล่าวคำทักทายที่แตกต่างกันออกไปสำหรับแต่อาชีพ ตอนนี้ให้คุณคัดลอกคาสทั้งสองไปแทนทีแบบเดิมที่ไม่มีการ override แล้วรันโปรแกรมดูใหม่

My name is Marcus
I'm an artist.
Marcus is playing Trip Hop music.

My name is Danny
I'm an athlete.
Danny is playing Football.

ซึ่งจะได้ผลลัพธ์การทำงานดังด้านบน การแนะนำจะต่างกันออกไปสำหรับแต่ละคลาส ซึ่งเกิดจากการ Override เมธอด introduce()

Tip: คุณสามารถทำการ Override เมธอด โดยไม่ต้องใช้คำสั่ง @Override ก็ได้ คอมไพลเลอร์ของภาษาจะทราบอัตโนมัติว่าเราทำการ Override เมื่อมีเมธอดที่ซ้ำกันกับ super class

คำสั่ง Super

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

class Artist extends Person {
    String genre;

    public Artist (String name, int age){
        super(name, age);
    }

    @Override
    public void introduce () {
        super.introduce();
        System.out.println("I'm an artist.");
    }

    public void playMusic () {
        System.out.println(name + " is playing " + genre + " music.");
    }
}

class Athlete extends Person {
    String sport;

    public Athlete (String name, int age){
        super(name, age);
    }

    @Override
    public void introduce () {
        super.introduce();
        System.out.println("I'm an athlete.");
    }

    public void playSport () {
        System.out.println(name + " is playing " + sport + ".");
    }
}

จากตัวอยางข้างบน เราได้ใช้คำสั่ง super ใน constructor ของคลาสย่อยในคำสั่ง super(name, age) เพราะมามันมีการทำงานเหมือนคลาสแม่ เราไม่จำเป็นต้องเขียนใหม่ ต่อมาเราได้ใช้ในเมธอด introduce super.introduce() เพื่อเรียกการทักทายจาก super class เช่นกัน เมื่อคุณนำคลาสข้างบนไปรันมันจะได้ผลลัพธ์เช่นเดียวกันกับตัวอย่างใน override ก่อนหน้า

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

บทความนี้เป็นประโยชน์หรือไม่?Yes·No