Implementation Inheritance #1: The Basic

    ฝันหนึ่งของโปรแกรมเมอร์ คือการที่เอา code ของใครก็ได้ที่เห็นว่าดีเอามาใช้ และถ้ามันไม่ตรงความต้องการนัก ก็ปรับ code เล็กน้อยก็เอาไปใช้งานได้ ตัวเองจะได้เขียน code น้อยๆ แต่ที่มันเป็นไปไม่ค่อยได้คือ เราไม่ค่อยได้ source code มา คนเขียนเขาหวง ทุกวันนี้มีความพยายามให้บริษัทต่างๆ เปิดเผย source code ของตัวเอง ที่เรียกเป็น สโลแกนว่า Open Source แต่ก็ไม่ได้รับการตอบรับจากบริษัทต่างๆ มากนัก ก็ของซื้อของขายน่ะครับ เขาล้มลุกคลุกคลานมากว่าจะคิดค้นได้ จะมาแจกกันฟรีๆ ได้ยังไง แต่กระนั้นก็ตาม ถึงแม้ว่าคุณได้ source code มา ก็ใช่ว่าคุณจะไป modify ของเขามาให้ตรงกับความต้องการของคุณได้ทันที คุณต้องไปเรียนรู้ source code ของเขาทั้งหมดอยู่ดี คุณก็แทบล้มประดาตายเหมือนกัน ถ้าคุณเคยอ่าน source code ของคนอื่นคุณจะเข้าใจที่ผมพูดครับ

        แนวคิดของทาง OOP พยายามจะช่วยแก้ปัญหานี้ครับ ทำได้ยังไง น่าคิด  มาดูกันหน่อย เริ่มต้น คุณอาจได้รับ code จากใครก็ตาม อาจจะได้มาในรูปที่ compiled แล้วเป็น .dll หรือ source code ก็ตามที เอามาใช้งาน ปรากฏว่ามันก็ใช้งานได้ดี แต่มันก็ไม่ถูกใจ มันน่าจะทำอะไรได้มากกว่าที่เขาให้มา ถ้า code นั้นเป็น Code ที่เขียนมาจากแนวคิดของการใช้ class คุณสามารถที่จะทำสิ่งที่เรียกว่า Inheritance ได้ นั่นก็คือการสร้าง class ใหม่ แล้วคุณสามารถโอนเอาความสามารถที่มีอยู่แล้วจาก class เดิมที่คุณได้มาจากคนอื่น เอามาเป็นความสามารถของ class ของคุณได้เลย และคุณยังสามารถเพิ่มเติมความสามารถให้กับ class ของคุณได้อีก ดังนั้น class ของคุณจึงมีความสามารถของทั้งของเดิม และของที่คุณเพิ่มเข้าไป ฟังดูดีไหมครับ

    เรามาเรียนกันเรื่องศัพท์เพิ่มเติมกันหน่อยดีกว่า

    เรามาเรียนรู้ความสัมพันธ์ของ class ที่ทำ Inheritance หน่อยดีกว่า มันมี 2 แบบ

IS-A


    ความสัมพันธ์ลักษณะนี้จะเป็นทำนองว่า  Base class เป็นเป็นของที่กว้างกว่า ส่วน Derived class เป็นของที่เจาะจงมากกว่า สมมุติว่า มีใครก็ตามสร้าง class ข้าวผัดขึ้นมา คุณเห็นว่าถ้าคุณเอามาใช้มันก็พอใช้ได้อยู่หรอก แต่มันยังไม่ตรงทีเดียว เพราะคุณจะทำข้าวผัดอเมริกัน คุณเลยสร้าง class ใหม่ที่ชื่อว่าข้าวผัิดอเมริกัน และ inherit มาจาก class ข้าวผัด วิธีการพิสูจน์ว่ามันเข้าข่าย IS-A ทำไม่ยากครับ  ให้ใช้ประโยคภาษาอังกฤษธรรมดา สร้างเป็น ประโยคดังนี้ครับ

    derived class IS A kind of base class?

    เช่น   ข้าวผัดอเมริกันเป็นข้าวผัดชนิดหนึ่ง? ถ้าคำตอบคือจริงมันก็เข้าข่าย IS-A แต่ถ้าไม่ใช่เช่น  รถยนต์เป็นจักรยานชนิดหนึ่ง? คำตอบคือไม่ใช่ ก็แสดงว่าไม่เข้าข่าย IS-A ครับ 

    การทำ Inheritance แบบ IS-A นั้นเป็นประเภทว่า เอา class ที่มีอยู่แล้วมาเพิ่มเติมความสามารถให้มากขึ้น

HAS-A 

    ความสัมพันธ์ลักษณะนี้เป็นแบบที่เหมือนอยู่บ้าง เราดึงความสามารถมาจาก class เก่า แต่ก็ไม่ใช่ทั้งหมดเอามาใช้งานได้ ใช้ได้เพียงบางส่วนเท่านั้น ยกตัวอย่างเก่าเรื่อง รถยนต์ และ จักรยาน ถ้าเรามี class จักรยานอยู่แล้ว และถ้าเราต้องการสร้าง class รถยนต์ เราก็สามารถ inherit ความสามารถของรถจักรยานได้ เช่นเอาส่วนของ ล้อ, เบรค, เกียร์ จากจักรยานไปได้ แต่ส่วนตีนถีบ หรือ โครงจักรยาน เอาไปก็ไม่ได้ใช้เพราะมันไม่มีในรถยนต์ ถ้าเข้าข่าย HAS-A ต้องตั้งคำถามดังนี้ครับ

    derived class HAS some Features of base class?

    ในกรณีนี้ รถยนต์ มีความสามารถบางส่วนของ จักรยาน? คำตอบคือใช่ มันคือ HAS-A

    การทำ Inheritance แบบ HAS-A นั้น เป็นประเภทเอา class ที่มีอยู่แล้ว ไม่ตรงกับงานนัก เอาเฉพาะส่วนที่ตรงมาใช้ แล้วเขียนเพิ่มเติมใน class ใหม่ให้สมบูรณ์ 

Implementation Inheritance ใน C#

    ภาษาที่ทำ Implementation Inheritance ได้สมบูรณ์์มากคือภาษา C++ แต่ C++ นั้นโลภมากไปหน่อยอยากให้ภาษาตัวเองเป็นเทวดาทำได้ทุกอย่าง เมื่อมันรองรับทุกอย่างได้ก็จริง แต่มันก็บวมครับ ภาษา C++ เลยเขียนยาก

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

    Java และ C# ตัดเอาความสามารถในการรองรับ HAS-A จาก C++ ออกไป นั่นก็หมายความว่า คุณใช้งาน Implementaion Inheritance นั้นคุณต้องใช้งานมันในรูป IS-A เท่านั้น ทำให้มันทำงานได้น้อยกว่าที่คุณหวังไว้ในตอนแรกครับ

Syntax

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

basic.cs

using System;
class Base 
{ 	public void func()
	{
		Console.WriteLine("Hello, World");
	}
}
class Derive : Base
{
}
class Start
{ 	public static void Main()
	{ 	
		Derive x = new Derive();
		x.func();
	}
} 

DOS Prompt

C:\CS>basic
Hello, World

C:\CS>_

    จากโปรแกรมนี้เราจะเห็นว่า class Base นั้นมี method ที่ชื่อว่า func() อยู่ แล้วคุณก็สร้าง class Derive มา เพื่อนำมา inherit class Base จะสังเกตว่าการ Inherit นั้น ใช้ Syntax  เพิ่มจากการสร้าง class ปกติคือใช้เครื่องหมาย : แล้วตามด้วยชื่อ class ที่ต้องการ inherit มา

    จากนั้น class Derive ก็ทำความสามารถทุกอย่างได้เหมือนกับที่ Base ทำได้

ผมว่าบทนี้ผมจบดื้อๆ แบบนี้ดีกว่า