ตอน 24 Inheritance และ Versioning ในภาษา C#

ไปหน้าแรก | สารบัญ | Laploy.comระเบียนบทความ | บทความจากลาภลอย

เว็บไซต์นี้เป็นตัวอย่างเนื้อหาบางตอนในหนังสือ "เรียนรู้ด้วยตนเอง OOP C# ASP.NET" ครอบคลุม บทที่ 1 ถึงบทที่ 6 (ในหนังสือมี 21 บท) ข้อเขียนในหนังสืออาจอาจแตกต่างจากใน Blog นี้ เพราะเป็นเนื้อหาที่ยังไม่ได้ตรวจแก้ขัดเกลา (edit)

กดที่นี่เพื่อดูรายละเอียดเนื้อหาในแต่ละบท

กดที่นี่เพื่อไปยังเว็บบอร์ด ถาม-ตอบ 

 

การดีบักยากกว่าการเขียนโค้ดสองเท่า ดังนั้นหากคุณเขียนโค้ดโดยใช้สติปัญญาทั้งหมดที่มี คุณจะโง่เกินกว่าที่จะดีบักมันได้
ไบรอัน ดับบลิว เคอร์นิกาน (บิดาภาษา C)

 

Inheritance และ Versioning ในภาษา C#

 

บทที่ 5 ภาษา C# ระดับก้าวหน้า

บทนี้ผู้เขียนจะอธิบายลักษณะพิเศษ (features) ต่างๆ ของภาษา C# ซึ่งเป็นเครื่องอำนวยให้เราเขียนโค้ดเป็น OOP ได้โดยสะดวกและสง่างาม ขอให้ท่านมอง features เหล่านี้เป็นเหมือนเครื่องมือที่บางอย่างเราต้องใช้บ่อยๆ บางอย่างนานๆ ครั้งจึงจะใช้ และบางอย่างก็ไม่มีโอกาสใช้เลย

ผู้เขียนรวบรวม features ระดับก้าวหน้าของภาษา C# ไว้ครบตั้งแต่ C# เวอร์ชันแรก ถึง c#3.0 แต่เนื่องจากภาษา C# มี features ก้าวหน้าจำนวนมาก จึงนำเสนอได้เพียงโดยย่อพอเป็นนิสัย สำหรับใช้เป็นความรู้เบื้องต้นเพื่อศึกษาในระดับสูงต่อไป

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

 

ในบทนี้ท่านจะได้เรียนเรื่องต่างๆ ต่อไปนี้

• Inheritance
• Versioning
• assignment
• type casting
• คำสั่ง as
• method overriding
• Name binding
• การทำ hiding
• Abstract
• Interface
• IEnumerator
• Indexer
• Iterator, yield
• Regex (Regular Expression)
• Generic
• Operator overloading
• Delegate
• Pointer และ Unsafe Code
• Implicitly typed local variables
• Lambda expressions
• Object และ collection initializes
• Anonymous types
• Implicitly typed arrays
• Query expressions
• Expression trees

 

inheritance

ท่านคงยังจำได้จากที่อ่านไปแล้วในบทที่ 1 ว่า inheritance คือหลักสำคัญอย่างหนึ่งใน OOP แม้หลักการ inheritance จะเรียบง่ายและสั้น อธิบายเพียงหนึ่งหน้าก็กินความครบถ้วน แต่ผลลัพธ์ที่ได้จากการ inheritance นั้นลึกซึ้งกินใจ จึงมีหัวข้อย่อยที่เกี่ยวพันกับ inheritance หลายหัวข้อที่ผู้เขียนจะพูดถึงต่อไปดังนี้

  • Syntax
  • Versioning
  • assignment
  • type casting
  • คำสั่ง as
  • method overriding
  • Name binding
  • การทำ hiding
  • Abstract

เนื่องจากเรื่อง inheritance ในภาษา C# ค่อนข้างยาว ผู้เขียนจึงจะแบ่งออกเป็นสามตอนดังนี้

  • ตอนที่ 1: Systax, Versioning
  • ตอนที่ 2: assignment, type casting, คำสั่ง as
  • ตอนที่ 3: method overriding, name bindgin การทำ hiding, abstract

 

Syntax

วากยสัมพันธ์ (syntax โครงสร้างตามแบบแผนของภาษา) ของ inheritance ในภาษา C# เป็นดังนี้

class A
{
    int a;
    public A() { }
    public void F() { }
}
class B : A
{
    int b;
    public B() { }
    public void G() { }
} 

ตัวอย่างโค้ดข้างบนคือรูปแบบการทำ inheritance ที่สมบูรณ์

ข้อสรุปเรื่อง inheritance

  • โค้ดข้างบนมีคลาสสองคลาส คือ A และ B
  • คลาส A คือ base class (หรือ super class)
  • คลาส B คือ derived class (หรือ sub class, child class)
  • การประกาศ inheritance ทำที่หัวของ derived class โดยใช้ชื่อของ base class ตามด้วยเครื่องหมายจุดคู่ และชื่อของ subclass (A:B)
  • มรดกที่คลาส B ได้รับจาก A คือ field a และ method F()
  • constructor ไม่เป็นมรดก
  • เราสามารถ override method ที่ได้รับมาเป็นมรดก (ไม่แสดงข้างบน)
  • ภาษา C# ให้ทำ inheritance ได้จาก base class เพียงคลาสเดียว
  • คลาสรับมรดกจาก struct ไม่ได้ รับได้จากคลาสเท่านั้น
  • คลาสทุกคลาสในภาษา C# ล้วนเป็น derived class
  • หากไม่ระบุ base class จะถือว่า base class คือ object

 

Versioning

versioning ในหัวข้อนี้เป็น versioning ในแง่มุมของการทำ inheritance เป็นหลักการที่ช่วยให้การพัฒนาซอฟท์แวร์แบบ OOP เป็นไปได้โดยไม่เกิดความขัดแย้ง โดยเฉพาะอย่างยิ่งการพัฒนา base class และ derived class โดยให้ทั้งคู่สามารถถูกแก้ไขเปลี่ยนแปลงเพื่อเพิ่มความสามารถ และเพิ่มประสิทธิภาพได้โดยไม่ขึ้นแก่กัน และไม่จำเป็นต้องอยู่ใน class library เดียวกัน

ยกตัวอย่างเช่นการเพิ่มสมาชิกใหม่ให้แก่ base class แม้จะมีชื่อซ้ำกับสมาชิกของ derived class ก็จะไม่ทำให้เกิด error การจะทำดังนี้ได้ผู้นิยามคลาสจะต้องประกาศให้รู้โดยเปิดเผยว่า method ใดบ้างที่override มาจาก method ที่ได้สืบสันดานมา หรือ method นั้น (แม้จะชื่อตรงกับ method ใน base class) แต่ก็เป็น method ใหม่ที่บัง method ใน base class ไว้

method ในภาษา C# ไม่ได้เป็น virtual โดยอัตโนมัติ (ไม่เหมือน Java) หากต้องการให้ method เป็น virtual (ดูรายละเอียดเรื่อง virtual ในหัวข้อ inheritance) ต้องกำหนด modifier virtual ไว้หน้านิยาม method ของ base class จากนั้น derived class สามารถ override method นั้นได้โดยใช้ keyword override หรือจะเพียงแค่บัง method นั้นก็ได้โดยการใช้ keyword new หน้านิยาม method ชื่อเดียวกันที่นิยามขึ้นใหม่ใน derived class ก็ได้

หากพยายามนิยาม method ใน derived class โดยมีชื่อตรงกับ method ใน base class โดยไม่ใส่ keyword override หรือ new ไว้หน้านิยาม method เมื่อคอมไพล์แม้จะไม่ error แต่จะมี warning ว่า method ใน derived class จะบัง method ใน base class โปรดพิจารณาโค้ดต่อไปนี้

public class MyBase
{
    public virtual string Meth1()
    {
        return "MyBase-Meth1";
    }
    public virtual string Meth2()
    {
        return "MyBase-Meth2";
    }
    public virtual string Meth3()
    {
        return "MyBase-Meth3";
    }
}

นี่คือนิยามคลาสที่เราจะใช้เป็น base class ในคลาสนี้มี method สาม method โดยเรากำหนดให้ทุก method มี modifier เป็นแบบ virtual ทั้งหมด

1     class MyDerived : MyBase
2     {
3         public override string Meth1()
4         {
5             return "MyDerived-Meth1"
6         }
7         public new string Meth2()
8         {
9             return "MyDerived-Meth2"
10        }
11        public string Meth3()
12        {
13            return "MyDerived-Meth3"
14        }
15    } 

โค้ดตัวอย่างข้างบนคือนิยามคลาสที่สืบสันดานจากคลาส MyBase จากนั้นนิยาม method ทับของเก่าครบทุก method บรรทัดที่ 3-6 นิยาม method Meth1() โดยใช้ keyword override ซึ่งเป็นการ override ตามปรกติ บรรทัดที่ 7-10 นิยาม method Meth2() โดยใช้ keyword new ซึ่งเป็นการทำ method hiding ตามปรกติ และบรรทัดที่ 11-15 นิยาม method Meth3() โดยไม่ได้ใช้ keyword override หรือ new ซึ่งเป็นการ override ที่ผิดปรกติ แม้เมื่อคอมไพล์แม้จะไม่ error แต่จะมี warning ว่า method Meth3() ใน derived class จะบัง method Meth3() ใน base class

จุดสำคัญเรื่อง versioning คือเมื่อเวลาผ่านไป หากผู้นิยาม derive class เพิ่มนิยาม method ดังนี้

class Base { }
class Derived : Base
{
    public void F() { }
} 

และต่อมาผู้นิยาม base class (ซึ่งไม่รู้ว่าผู้นิยาม derived class ได้เพิ่มนิยาม method ใดๆ อะไรไปบ้างหรือไม่) ได้เพิ่ม method ใน base class ของตนดังนี้

class Base
{
    public void F() { }
}
class Derived : Base
{
    public void F() { }
} 

ซึ่ง method นี้มีชื่อซ้ำกันกับ method ที่ผู้นิยาม derived class ได้เพิ่มไปก่อนหน้านั้นแล้ว สภาพการณ์อย่างนี้ไม่ก่อให้เกิดความขัดแย้งหรือความยุ่งยากใดๆ เพราะภาษา C# ยอมให้ derived class มี method ชื่อซ้ำกับ base class ได้แม้ base class จะไม่ได้กำหนดให้ method นั้นเป็น virtual ก็ตาม และแม้ derived class จะไม่ใช้ keyword override หรือ new ก็ยังคอมไพล์ผ่านได้ (compiler จะแจ้งเตือนว่ามีนิยาม method ซ้อนทับกัน แต่ไม่ถือว่าเป็นความผิดร้ายแรงจนโปรแกรมไม่อาจทำงานได้)

ตอนต่อไป : assignment, type casting และคำสั่ง as

Post a comment or leave a trackback: Trackback URL.

ความเห็น

  • Pla  On กุมภาพันธ์ 14, 2007 at 11:11 am

    เราอย่างได้ตัวอย่างcod c#ที่มันใช้ทำบัญชีอ่ะเช่น   เช้นบัญชีเงินฝากพวกนี้อ่ะ  ขอบคุงมากค่ะ

ใส่ความเห็น

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / เปลี่ยนแปลง )

Twitter picture

You are commenting using your Twitter account. Log Out / เปลี่ยนแปลง )

Facebook photo

You are commenting using your Facebook account. Log Out / เปลี่ยนแปลง )

Google+ photo

You are commenting using your Google+ account. Log Out / เปลี่ยนแปลง )

Connecting to %s

%d bloggers like this: