Polymorphism

29 August 2016

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

Polymorphism คืออะไร

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

ในการเขียนโปรแกรมเชิงวัตถุ Polymorphism นั้นคือการสร้างออบเจ็คโดยเป็นออบเจ็คที่สร้างมาจากคลาสที่มี Super class เดียวกัน โดยใน Sub class นั้นได้มีการกำหนดการทำงานใหม่ให้กับเมธอดให้ตรงกับวัตถุประสงค์ของคลาสนั้น หรือการ Override method หลังจากนั้นเราสามารถใช้ Super class สำหรับการประกาศตัวแปรของออบเจ็ค (class instance) ที่สร้างออบเจ็คจาก Sub class ได้

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

public class TestPolymorphism {

    public static void main (String[] args) {

        Person person1, person2, person3;
        person1 = new Person("Mark", 1980);
        person2 = new Sheriff("Mateo", 1981, "California");
        person3 = new Police("Danny", 1986, "NYC");

        person1.introduce();
        person2.introduce();
        person3.introduce(); 

    }  

}

class Person {

    String name;
    int bornYear;

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

    public void introduce () {
        System.out.print("My name is " + name + ",");
        System.out.println(" I was born in " + bornYear + ".");
    }

}

class Sheriff extends Person {

    String workState;

    public Sheriff (String name, int bornYear, String workState) {
        super(name, bornYear);
        this.workState = workState;
    }

    @Override
    public void introduce () {
        super.introduce();
        System.out.println("I'm a sheriff and work in " + 
                workState + ".");
    }

}

class Police extends Person {

    String workCountry;

    public Police (String name, int bornYear, String workCountry) {
        super(name, bornYear);
        this.workCountry = workCountry;
    }

    @Override
    public void introduce () {
        super.introduce();
        System.out.println("I'm a police and work in " + 
                workCountry + ".");
    }

}

ในตัวอย่าง นั้นเรามีคลาส Person ที่เป็น super class เราได้สร้าง delivered class มาสองคลาสคือ Sheriff และ Police นั่นคือเป็นคลาสที่สืบทอดคุณสมบัติของตัวแปรและเมธอดมาจากคลาส Person

ใน delivered class ทั้งสอง เราได้ทำการ override เมธอด introduce เพื่อแสดงข้อมูลเพิ่มเติม และต่อไปเป็นการใช้งานคุณสมบัติของ polymorphism ในจากโค้ด

Person person1, person2, person3;
person1 = new Person("Mark", 1980);
person2 = new Sheriff("Mateo", 1981, "California");
person3 = new Police("Danny", 1986, "NYC");

ในตอนนี้ เราได้ใช้คลาส Person ในการประกาศออบเจ็ค (instances) มา 3 ตัวแปร และเราใช้ instances ของคลาสนี้ในการสร้างออบเจ็คจากคลาสต่างๆ ซึ่งก็คือ Person, Sheriff และ Police นั่นหมายความว่า ตัวแปรที่สร้างจากคลาส Person นั้นมีได้หลายรูปแบบ ในตัวอย่างนั้นมี 3 แบบด้วยกัน

person1.introduce();
person2.introduce();
person3.introduce(); 

ต่อมาเป็นการเรียกใช้งานเมธอด introduce ของแต่ละออบเจ็คซึ่งสร้างมาจากคลาสที่แตกต่างกัน สำหรับ delivered class นั้นเมธอด introduce ถูกทำการ override เพื่อให้แสดงข้อมูลเพิ่มเติม

ข้อได้เปรียบของ polymorphism คือการที่สามารถจัดการกับออบเจ็คที่สืบทอดมาจากคลาสเดียวกันได้ โดยใช้ super class ของมันในการประกาศออบเจ็ค

My name is Mark, I was born in 1980.
My name is Mateo, I was born in 1981.
I'm a sheriff and work in California.
My name is Danny, I was born in 1986.
I'm a police and work in NYC.

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

Warning: ในการใช้ instances ที่สร้างจาก super class สามารถใช้ได้กับตัวแปรหรือเมธอดที่มีอยู่ใน super class หรือที่ได้รับการ override เท่านั้น ยกตัวอย่างเช่น ถ้าคุณสร้างเมธอดหรือตัวแปรใหม่ใน delivered class คุณไม่สามารถใช้มันได้ผ่าน instance ของ super class ได้ เราจะพูดเกี่ยวกับเรื่องนี้ในเรื่อง interface และ abstract class

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

import java.util.ArrayList;

public class Polymorphism {

    public static void main(String[] args) {

        ArrayList<Shape> shapes = new ArrayList<Shape>();
        shapes.add(new Rectangle());
        shapes.add(new Triangle());

        for (Shape shape : shapes) {
            drawShape(shape);
    }

    }

    public static void drawShape(Shape shape) {
        shape.draw();
    }

}

class Shape {

    public void draw() {
        System.out.println("Perform draw from base class");
    }

}

class Rectangle extends Shape {

    @Override
    public void draw() {
        System.out.println("Draw rectangle");
        super.draw();
    }

}

class Triangle extends Shape {

    @Override
    public void draw() {
        System.out.println("Draw triangle");
        super.draw();
    }

}

ในตัวอย่าง เรามีคลาส Shape ในการกำหนดรูปทรง ซึ่งคลาสนี้มีเมธอด draw() เพื่อเป็นการวาดรูปทรงในคลาส และต่อมาเราได้สร้างอีกสองคลาสคือ Rectangle และ Triangle ที่มีการสืบทอดมาจากคลาส Shape และทำการ Override เมธอด draw() เพื่อให้สอดคล้องกับการทำงานของคลาสทั้งสอง

ArrayList<Shape> shapes = new ArrayList<Shape>();
shapes.add(new Rectangle());
shapes.add(new Triangle());

for (Shape shape : shapes) {
    drawShape(shape);
}

ในการเริ่มทำงานของโปรแกรม เราได้สร้าง ArrayList โดยการใช้คลาส Shape เป็น instance ของออบเจ็ค ดังนั้นเราจึงสามารถนำไปสร้างออบเจ็คที่สืบทอดจากจากคลาสนี้ได้ นั่นก็คือเราได้สร้างออบเจ็คจากคลาส Rectangle และ Triangle และเก็บใน ArrayList ดังนั้น ตัวแปร shapes สามารถมีได้หลายรูปแบบของออบเจ็คที่สืบทอดจาดคลาส Shape ซึ่งนี่เองถือเป็นแนวคิดของการใช้งาน Polymorphism

public static void drawShape(Shape shape) {
    shape.draw();
}

นอกจากนี้ เมธอด drawShape() เป็นเมธอดสำหรับการวาดรูปทรงที่มีพารามิเตอร์เป็น Shape ดังนั้นเราไม่ต้องสนใจว่าออบเจ็คที่ส่งเข้ามาจะเป็นออบเจ็คของ Rectangle หรือ Triangle ซึ่งเราสนใจแต่สิ่งที่เราต้องการทำคือการเรียกใช้งานเมธอด draw() ซึ่งกลไกลของ Polymorphism จะเรียกใช้งานเมธอดของออบเจ็คอัตโนมัติ

Draw rectangle
Perform draw from base class
Draw triangle
Perform draw from base class
Draw circle
Perform draw from base class

นี่เป็นผลลัพธ์การทำงานของโปรแกรมในการใช้งาน Polymorphism กับอาเรย์และเมธอด

ในบทนี้ คุณได้เรียนรู้เกี่ยวกับ polymorphism ในภาษา Java ซึ่งเราสามารถจัดการกับออบเจ็คต่างประเภทกัน โดยใช้ instances จาก super class ของมันได้

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