Inheritance
ในบทนี้ คุณจะได้เรียนรู้เกี่ยวกับ Inheritance (การสืบทอด) ในภาษา C# ซึ่งเป็นคุณสมบัติที่สำคัญในการเขียนโปรแกรมเชิงวัตถุในการสืบทอดคุณสมบัติของคลาสเดิมไปใช้ในคลาสใหม่
Inheritance คืออะไร
Inheritance (การสืบทอด) เป็นคุณสมบัติหนึ่งในการเขียนโปรแกรมที่ใช้กับการสร้างคลาส โดยการถ่ายทอดสมาชิกจากคลาสหนึ่งไปยังอีกคลาสหนึ่ง โดยสมาชิกที่ว่านี้ก็คือสมาชิกของคลาสนั้นเอง ซึ่งมีตัวแปรและเมธอด ในภาษา C# เราเรียกคลาสหลักที่สืบทอดไปยังคลาสอื่นว่า Base class และคลาสที่ถูกสืบทอดนั้นจะเรียกว่า Delivered class
ตัวอย่างของการสืบทอดคลาสกับการใช้งานจริง เช่น เรามีคลาสของสัตว์ซึ่งเป็น Base class คลาสนี้มีคุณสมบัติและการทำงานบางอย่างที่สัตว์ทุกชนิดสามารถทำได้ หลังจากนั้นเราอาจจะมีการสร้างคลาสใหม่ที่มีการสืบทอดจากคลาสนี้ ซึ่งเป็นสัตว์แต่ละชนิด เป็นต้น
ในการสืบทอดในภาษา C# นั้นจะใช้เครื่องหมายโคลอน (colon) :
โดยมีรูปแบบการสร้างคลาสเพื่อสืบทอดดังนี้
class DeliveredClass: BaseClass {
// statemets
}
จากรูปแบบด้านบนนั้นเป็นวิธีของการเขียนโปรแกรม โดยมีความหมายว่า BaseClass สืบทอดคุณสมบัติทั้งหมดไปยัง DeliveredClass ในตอนนี้ DeliveredClass มีคุณสมบัติเท่ากับ BaseClass และนอกจากนี้มันยังสามารถเพิ่มสมาชิกไม่ว่าจะเป็นตัวแปรหรือเมธอดได้ ดังนั้น Delivered class จะมีคุณสมบัติหรือประสิทธิภาพเท่ากับหรือมากกว่า Base class เสมอ
ในการสืบทอดนั้นสมาชิกที่มีการกำหนดการเข้าถึงเป็น private จะถูกสืบทอดไปยังคลาสย่อย และนอกจากนี้ Constructor และ Destructor ยังไม่สามารถสืบทอดด้วยเช่นกัน ต่อไปมาดูตัวอย่างของการ Inheritance ในภาษา C#
สร้าง Inheritance คลาส
ต่อไปมาดูตัวอย่างของการใช้งานคุณสมบัติการสืบทอด เพื่อสืบทอดคุณสมบัติของคลาสในภาษา C# เราจะทการสร้างคลาสของรูปสี่เหลี่ยมมูมฉาก (Rectangle) หลังจากนั้นเราจะสร้างคลาสที่สืบทอดคุณสมบัติจากคลาสนี้คือคลาสของรูปสี่เหลี่ยมมุมฉากในสามมิติ (Cuboid)
using System;
class InheritanceExample
{
static void Main(string[] args)
{
Rectangle rec1 = new Rectangle(3, 4);
Console.WriteLine("Rectangle 1");
Console.WriteLine("size [{0}, {1}]", rec1.x, rec1.y);
Console.WriteLine("Area = {0}", rec1.GetArea());
Console.WriteLine();
Cuboid cub1 = new Cuboid(5, 3, 4);
Console.WriteLine("Cuboid 1");
Console.WriteLine("size [{0}, {1}, {2}]",
cub1.x, cub1.y, cub1.z);
Console.WriteLine("Volume = {0}", cub1.GetVolume());
Console.WriteLine();
Cuboid cub2 = new Cuboid(10, 10, 10);
Console.WriteLine("Cuboid 2");
Console.WriteLine("size [{0}, {1}, {2}]",
cub2.x, cub2.y, cub2.z);
Console.WriteLine("Volume = {0}", cub2.GetVolume());
}
}
class Rectangle
{
public int x;
public int y;
public Rectangle(int x, int y)
{
this.x = x;
this.y = y;
}
public double GetArea()
{
return x * y;
}
}
class Cuboid : Rectangle
{
public int z;
public Cuboid(int x, int y, int z) : base(x, y)
{
this.z = z;
}
public double GetVolume()
{
return GetArea() * z;
}
}
ในตัวอย่าง เราได้สร้างคลาส Rectangle
ซึ่งเป็นคลาสของรูปสี่เหลี่ยมมุมฉาก ที่ประกอบไปด้วยความยาวในแนวแกน x และ y และมีเมธอด GetArea()
สำหรับหาพื้นที่ของรูปสี่เหลี่ยม ซึ่งคลาสนี้เป็นคลาสของรูปสี่เหลี่ยมในสองมิติ
class Cuboid : Rectangle
{
public int z;
public Cuboid(int x, int y, int z) : base(x, y)
{
this.z = z;
}
public double GetVolume()
{
return GetArea() * z;
}
}
ต่อมาเราได้สร้างคลาส Cuboid
ซึ่งเป็นคลาสของสี่เหลี่ยมในสามมิติ และคล่าได้สืบทอดมาจากคลาส Rectangle
ดังนั้นคลาส Cuboid
จะได้รับคุณสมบัติทั้งหมดที่มีใน Base class ที่ประกอบไปด้วยตัวแปรและเมธอด และเราได้สร้างตัวแปร z
สำหรับเก็บความยาวในแกน z และสร้างเมธอด GetVolume()
สำหรับหาปริมาตรของรูปทรงสี่เหลี่ยมนี้
และในการสืบทอดนั้น Constructor จะไม่สืบทอดมาด้วย ดังนั้นใน Constructor ของคลาส Cuboid
เราได้เรียกใช้ Constructor ของ base class ด้วยคำสั่ง : base(x, y)
ตามหลัง Constructor ของมันเอง
Rectangle 1
size [3, 4]
Area = 12
Cuboid 1
size [5, 3, 4]
Volume = 60
Cuboid 2
size [10, 10, 10]
Volume = 1000
นี่เป็นผลลัพธ์การทำงานของโปรแกรม เราได้นำคลาสทั้งสองมาสร้างออบเจ็คของรูปสี่เหลี่ยมและรูปทรงสี่เหลี่ยม เราได้ลดการเขียนโปรแกรม โดยการใช้งานคุณสมบัติบางส่วนจากคลาส Rectangle
โดยการที่ไม่ต้องประกาศตัวแปร x
y
และเมธอด GetArea()
ใหม่จากการ Inheritance ของคลาสหรือมันเป็นการ reuse code
Note: คุณสมบัติที่เป็นแบบ private จะไม่สามารถถ่ายทอดได้ เราจำเป็นต้องเปลี่ยนตัวแปร width และ height เป็น protected ก่อน
Overriding Base Class
ในการสืบทอดนั้น ยังมีความสามารถที่เราสามารถทำการ Override ซึ่งคือการที่ Delivered Class สามารถที่จะกำหนดการทำงานให้กับเมธอดใหม่เพื่อให้สอดคล้องกับการทำงานในคลาส ต่อไปเป็นตัวอย่างของการ Override คลาสในภาษา C#
using System;
class OverrideExample
{
static void Main(string[] args)
{
AddNumber x = new AddNumber();
x.a = 2;
x.b = 3;
Console.WriteLine("{0} + {1} = {2}", x.a , x.b, x.Result());
MultiplyNumber y = new MultiplyNumber();
y.a = 4;
y.b = 5;
Console.WriteLine("{0} * {1} = {2}", y.a, y.b, y.Result());
}
}
class AddNumber
{
public int a;
public int b;
public virtual int Result()
{
return a + b;
}
}
class MultiplyNumber : AddNumber
{
public override int Result()
{
return a * b;
}
}
ในตัวอย่าง เรามีคลาส AddNumber
ซึ่งเป็นคลาสสำหรับบวกตัวเลขสองตัว และคลาสนี้มีเมธอดสำหรับหาผลลัพธ์ของการบวกตัวเลขคือเมธอด Result()
และเราได้ใช้คำสั่ง virtual
ในการประกาศเมธอดเพื่อกำหนดให้เมธอดนี้สามารถที่จะ Override ได้โดย Delivered Class ของมัน
class MultiplyNumber : AddNumber
{
public override int Result()
{
return a * b;
}
}
เราสร้างคลาส MultiplyNumber
และได้สืบทอดจากคลาส AddNumber
คลาสนี้เป็นคลาสสำหรับหาผลคูณของตัวเลขสองตัว และในเมธอด Result()
เราต้องทำการเปลี่ยนแปลงสมการสำหรับการคูณ และเราต้องการใช้ชื่อเมธอดเดิมกับคลาสหลัก เราจะใช้คำสั่ง override
ในการประกาศเมธอด
2 + 3 = 5
4 * 5 = 20
นี่เป็นผลลัพธ์การทำงานของโปรแกรม คุณจะเห็นว่าเราได้ทำการ override เมธอด Result()
ใหม่สำหรับในคลาสของการคูณตัวเลข ดังนั้นสิ่งที่สำคัญของการ override คือเราสามารถใช้เมธอดชื่อเดียวกันแต่ผลลัพธ์การทำงานต่างกันตามวัตถุประสงค์ของคลาส
ในบทนี้คุณได้เรียนรู้เกี่ยกวับคุณสมบัติ Inheritance ในการเขียนโปรแกรมเชิงวัตถุที่มีในภาษา C# และการ Override และการใช้คำสั่ง base ในการเข้าถึง Base class ของมัน