Polymorphism #5 : Collection of Objects

    เรามาถึงการประยุกต์ใช้ Polymorphism ที่สำคัญคือ การใช้ Collection of Object ที่จริงแล้วมันเป็นส่วนขยายของ Reuse Method นั่นเอง 

    ใจจริงผมอยากจะแสดงให้เห็นจริงๆ เลยว่างานจริงๆ เขาทำกันยังไงโดยใช้ Collection แต่ติดตรงที่ผมยังไม่เคยแนะนำเรื่อง Collection ให้คุณเคย ถ้าเอาตัวอย่างเป็น Collection เกรงว่าเราต้องเรียนเรื่องไม่เคยเรียน 2 เรื่อง เกรงว่าจะสับสน ผมเลยแปลงเนื้อหาเป็น Array เพราะมันมีส่วนคล้ายกับ Array อยู่ แล้วพอคุณรู้เรื่อง Collection แล้วก็ประยุกต์เอาเองนะครับ

    จากตัวอย่างในบทก่อนเรื่อง Reuse Method นั้นคุณคงเห็นแล้วว่าเราจะประยุกต์ใช้ Polymorphism อย่างง่ายได้อย่างไร มาบทนี้เราจะเรียนรู้การใช้ Polymorphism ที่ประยุกต์ใช้ในงานจริงๆ คือเรื่อง Collection of Object

    ผมเริ่มจากการที่เรามี Array ตัวหนึ่ง (จริงๆ แล้วควรเป็น Collection) Array ตัวนี้เก็บตัวชี้ไปยัง object ครับ เป็น object เกี่ยวกับ Polymorphism นั่นแหละครับ สมมุติว่า บริษัทของคุณมีพนักงาน 1000 คน ซึ่งมีตำแหน่งต่างๆ กันอยู่ถึง 50 ตำแหน่ง แทนที่คุณจะต้อง handle งานที่แตกต่างกัน 50 แบบ คุณสร้าง Array ที่เก็บตัวชี้แบบ Employee ซึ่งมันสามารถชี้ได้ทั้ง 50 แบบ ตามหลัก Polymorphism ที่เราเรียนในบทก่อน จากนั้นคุณก็สามารถสร้าง Reuse Method เพื่อสั่งการทั้ง 50 แบบนี้ได้ภายใน Code เดียว ใช้การวน loop ในการสั่งงานครับ ข้อดีก็อย่างที่ทราบๆ กันนะครับ คือ code เดียวทำงานได้ทั้ง 50 แบบ และที่สำคัญคือสามารถเพิ่มตำแหน่งที่ 51 52 ได้ไปเรื่อยๆ โดยที่ไม่ต้องแก้ code ผู้เรียก เรามาดูตัวอย่างกัน

collection.cs

using System;
abstract class Employee
{
	protected string name;
	protected int hours;
	abstract public int pay();
}
class Engineer : Employee
{ 	
	public Engineer(string Name, int hours)
	{ 		
	this.name = Name;
	this.hours = hours;
	}
	public override int pay()
	{
		return hours *  150;
	} 
}
class Manager : Employee
{
	public Manager(string Name, int hours)
	{ 		
		this.name = Name;
		this.hours = hours;
	}
	public override int pay()
	{
		return hours *  400;
	} 
}
class Worker : Employee
{
	public Worker(string Name, int hours)
	{ 		
		this.name = Name;
		this.hours = hours;
	}
	public override int pay()
	{
		return hours *  30;
	} 
}
class Start
{
	private static  Employee[] employees;
	public static void Init()
	{
		employees = new Employee[10];
		employees[0] = new Manager("Supoj", 50);
		employees[1] = new Worker("Suwit", 100);
		employees[2] = new Engineer("Narathip", 40);
		employees[3] = new Engineer("Anupong", 50);
		employees[4] = new Worker("Chalerm", 60);
		employees[5] = new Engineer("Jitra", 30);
		employees[6] = new Engineer("Ram", 30);
		employees[7] = new Worker("Charlard", 100);
		employees[8] = new Manager("Niti", 20);
		employees[9] = new Worker("Passakorn", 50);
	}
	
	public static int ShowPayMent()
	{
		int sum = 0;
		for (int i=0; i<employees.Length; i++) 
		{
			sum += employees[i].pay();
		}
		return sum;
	}
	
	public static void Main()
	{
		Init();
		Console.WriteLine("This company has to pay {0} baht this period", PayMent());
	}
}

DOS Prompt

C:\CS>collection
This company has to pay 59800 baht this period


C:\cs>_

    เอาอย่างย่อๆ นะครับ ผมสร้าง array of employees ที่ชื่อว่า employees ขึ้นมาแต่ละ element ใน employees จะสามารถเก็บตำแหน่งงานอะไรก็ได้ ผมก็เลยใส่ค่าต่างๆ กันให้มันใน Init() จากนั้น เราสามารถสร้าง Reuse Method ที่ชื่อว่า ShowPayMent() ไปดึงเอา ค่า pay() ด้วยกลไกของ polymorphism มันจะไปดึงเอา override method pay() มาใช้อย่างถูกต้องทำให้เราทำผลรวมได้

    ผมเองตอนเขียนโปรแกรมส่วนกลาง ผมก็ใช้วิธีนี้เหมือนกัน แต่ไม่ได้ใช้กับ Implmentation Inheritance แบบตัวอย่างนี้นะครับ ผมใช้กับ Interface-based Inheritance ซึ่งใช้งานได้ดีมากครับ

    หลักการที่เขียนมานี้ถูกนำไปประยุกต์อย่างกว้างขวาง windows ต่างๆ ใน Microsoft Windows ก็ใช่ ยกตัวอย่างเช่น คุณเคยเห็น พอเอา windows หนึ่งซ้อนอีก windows หนึ่งรึเปล่าครับ ในวันที่เครื่องคอมพิวเตอร์ทำงานหนัก คุณจะสังเกตว่า windows ที่ถูกซ้อนนั้นเนื้อหาหายหมด เป็นจอขาวๆ อาจจะรอหลายนาทีเนื้อหาใน windows นั้นถึงจะได้คืนมา ที่เป็นอย่างนี้ก็เพราะ windows ใช้หลักการ polymorphism ให้สิ่งต่างๆ เช่น control ต่างๆ มี Method ที่ชื่อว่า Paint() ที่จะทำการ refresh windows ตามช่วงเวลา ทุก control ก็ต้อง มี Method Paint() พอนึกภาพออกไหมครับ

     พวกเกมส์ต่างๆ ก็ใช้ ใช้ตรงที่ว่า มันจะเก็บตัว object ของเราและ object ของศัตรูลงบน collection และมันจะวันรอบเพื่อสั่ง method run() ใน method run() นี้เองก็แล้วแต่ว่า object นั้นเป็น object อะไร การทำงานของเกมส์นี้จะเป็นรอบๆ แต่โดยศักยภาพของเครื่องคอมพิวเตอร์ทำให้เรารู้สึกว่ามาทำงานต่อเนื่องกัน ไม่เห็นเป็นรอบ ๆ