Inheritance
ในบทนี้ คุณจะได้เรียนรู้เกี่ยวกับการสืบทอดในภาษา Visual Basic ซึ่งเป็นคุณสมบัติที่คลาสสามารถถ่ายทอดไปยังคลาสใหม่ได้ ซึ่งเป็นคุณสมบัติที่สำคัญในการเขียนโปรแกรมเชิงวัตถุ
Inheritance คืออะไร
ในการเขียนโปรแกรมเชิงวัตถุ inheritance (การสืบทอด) คือการที่คลาสนั้นสร้างมาจากคลาสอื่น ในภาษา Visual Basic นั้น เราสามารถใช้คุณสมบัตินี้ในการสร้างคลาสใหม่ (delivered class) ซึ่งสามารถสืบทอดคุณสมบัติ เมธอด หรืออีเวนต์ ของคลาสหลักได้ (base class) นอกจากนี้ ในคลาสใหม่ยังสามารถกำหนดสมาชิกของมันได้เพิ่มเติม หรือกล่าวอีกนัยหนึ่ง การสืบทอดคือการที่คลาสสร้างมาจากคลาสอื่นและต่อเติมความสามารถเพิ่มสำหรับตัวมันเอง
ในการสร้างคลาสที่สืบทอดจะใช้คำสั่ง Inherits
ตามด้วยชื่อของ base class ในบรรทัดแรกภายในบล็อคของ delivered class มาดูตัวอย่างการสืบทอดคลาสในภาษา Visual Basic
Class Rectangle
Public width As Integer
Public height As Integer
Function Area() As Integer
Return width * height
End Function
End Class
Class Hyperrectangle
Inherits Rectangle
Public depth As Integer
Function Volume() As Integer
Return width * height * depth
End Function
End Class
นี่เป็นตัวอย่างการสืบทอดของคลาสในภาษา Visual Basic เราได้สร้าง base class คือคลาส Rectangle
ซึ่งเป็นคลาสของรูปสี่เหลี่ยมในสองมิติ ในคลาสนี้มีสมาชิกที่เป็นตัวแปรสำหรับเก็บความยาวของรูปสี่เหลี่ยม และเมธอดสำหรับหาพื้นที่
ต่อมาเราสร้างคลาส Hyperrectangle
ซึ่งทำการสืบทอกจากคลาส Rectangle
เราเรียกคลาสที่สร้างมานี้ว่า delivered class โดยมันจะมีตัวแปรและเมธอดเหมือนกับ base คลาสทุกอย่าง ในคลาสใหม่นี้เรายังประกาศตัวแปรและสร้างเมธอดเพิ่มเติม ต่อไปมาดูตัวอย่างการสร้างออบเจ็คและใช้งาน
Class Rectangle
Public width As Integer
Public height As Integer
Function Area() As Integer
Return width * height
End Function
End Class
Class Hyperrectangle
Inherits Rectangle
Public depth As Integer
Function Volume() As Integer
Return width * height * depth
End Function
End Class
Module InheritanceExample
Sub Main()
Dim box As Hyperrectangle = New Hyperrectangle()
box.width = 3
box.height = 4
box.depth = 5
Console.WriteLine("Box1 area = {0}", box.Area())
Console.WriteLine("Box1 volume = {0}", box.Volume())
End Sub
End Module
นี่เป็นการนำคลาสที่เราสืบทอดมาสร้างออบเจ็ค เราสามารถนำมาสร้างและเรียกใช้งาน property เหมือนการสร้างออบเจ็คในคลาสปกติ เหมือนที่คุณเห็นในตัวอย่าง ตัวแปรออบเจ็ค Hyperrectangle
สามารถเข้าถึงตัวแปรและเมธอดที่มันสืบทอดมาเหมือนเป็นของตัวมันเอง
Box area = 12
Box volume = 60
นี่เป็นผลลัพธ์ของโปรแกรมในตัวอย่างการสืบทอดคลาสในภาษา Visual Basic
Info: การสืบทอดในภาษา Visual Basic ตัวแปร property เมธอด และอีเว้นต์ จะถูกสืบทอดไปยังคลาสใหม่ทั้งหมด ยกเว้นตัวแปรที่มีระดับการเข้าถึงเป็น Private และคอนสตรัคเตอร์ของคลาสที่จะไม่ถูกสืบทอด
Overriding method
ในการสืบทอดคลาสในภาษา Visual Basic นั้นเมธอดของ base class จะถูกสืบทอดมาด้วย และมันยังคงรักษาการทำงานจากคลาสเดิมอยู่ เราสามารถทำการ override เมธอดโดยที่เมธอดยังมีชื่อเหมือนเดิมกับ base class แต่การทำงานจะเปลี่ยนไปใน delivered class มาดูตัวอย่างการ override เมธอด
Class AnnualSalary
Overridable Function PayEmployee(
ByVal salary As Double) As Decimal
PayEmployee = salary * 12
End Function
End Class
Class BonusAnnualSalary
Inherits AnnualSalary
Public bonusRate = 1.8
Overrides Function PayEmployee(
ByVal salary As Double) As Decimal
PayEmployee = MyBase.PayEmployee(salary) * bonusRate
End Function
End Class
Module OverrideMethod
Sub Main()
Dim annualSal As New AnnualSalary()
Dim annualSalWithBonus As New BonusAnnualSalary()
Dim salary As Double = 6628
Console.WriteLine("Your salary $" & salary)
Console.WriteLine("Your annual salary is $" &
annualSal.PayEmployee(salary))
Console.WriteLine("Your annual salary with bonus is $" &
annualSalWithBonus.PayEmployee(salary))
End Sub
End Module
ในตัวอย่างเป็นโปรแกรมในการคำนวณหารายได้ประจำปี โดยคำนวณจากเงินเดือน เราได้สร้างคลาสมาสองคลาสสำหรับตัวอย่างการ override method นี้
Class AnnualSalary
Overridable Function PayEmployee(
ByVal salary As Double) As Decimal
PayEmployee = salary * 12
End Function
End Class
นี่เป็นคลาสหลักของเรา และมันมีเมธอด PayEmployee()
สำหรับคำนวณรายได้ต่อปี เราใช้คำสั่ง Overridable
เพื่อกำหนดให้เมธอดนี้สามาร override ได้ใน delivered class ที่คุณเห็นในโปรแกรม การใช้คำสั่ง PayEmployee = salary * 12
นั้นให้ผลลัพธ์เหมือนกันกับคำสั่ง Return
Class BonusAnnualSalary
Inherits AnnualSalary
Public bonusRate = 1.8
Overrides Function PayEmployee(
ByVal salary As Double) As Decimal
PayEmployee = MyBase.PayEmployee(salary) * bonusRate
End Function
End Class
ต่อมาเราได้สร้างคลาส BonusAnnualSalary
ซึ่งสืบทอดจากจากคลาส AnnualSalary เราได้ทำการ override method PayEmployee()
จาก base class โดยข้างหน้าเมธอดเราใช้คำสั่ง Overrides
และภายในเมธอดนี้ เรายังสามารถเข้าถึงเมธอดของ base class ได้ด้วยคำสั่ง MyBase.PayEmployee(salary)
Your salary $6628
Your annual salary is $79536
Your annual salary with bonus is $143164.8
นี่เป็นผลลัพธ์ของโปรแกรมที่มีอัตราของโบนัสอยู่ 1.8 จากการมีเงินเดือน $6628 จะมีรายได้ต่อปีพร้อมโบนัสเป็น $143164.8
การใช้คำสั่ง Me และ MyBase
การสืบทอดคลาสนั้นทำให้เราสามารถนำโค้ดเดิมกลับมาใช้ได้โดยไม่ต้องเขียนใหม่ทั้งหมด หลังจากที่การสืบทอดสำเร็จ delivered class จะมีตัวแปรและเมธอดเหมือนกันกับ base class ทุกอย่าง ทำให้การใช้งานภายในคลาสนั้นอ้างถึงสมาชิกของตัวเอง ดังนั้นคุณจำเป็นต้องทราบในการใช้งานของคำสั่ง Me และ MyBase
- คำสั่ง Me: เป็นคำสั่งในการอ้างถึงสมาชิกของออบเจ็คหรือคลาสปัจจุบัน โดยปกติการเข้าถึงสมาชิกภายในคลาสปัจจุบันนั้นใช้คำสั่งนี้โดยปริยาย
- คำสั่ง MyBase: เป็นคำสั่งในการอ้างถึงสมาชิกของออบเจ็คหรือคลาสของ base class โดยการเรียกใช้นั้นอยู่ใน delivered class
เหมือนที่คุณเห็นในตัวอย่างก่อนหน้าที่เราได้ใช้คำสั่ง MyBase ไปแล้ว การอ้างถึงสมาชิกของคลาสหรือออบเจ็คนั้นจะยึดจากคลาสปัจจุบันที่เรียกใช้คำสั่งเหล่านี้ มาดูตัวอย่างเพื่อให้คุณเข้าใจได้มากขึ้น
Class Point2D
Public x As Double
Public y As Double
Sub New(ByVal x As Double, ByVal y As Double)
Me.x = x
Me.y = y
End Sub
Function Distance(ByVal point As Point2D) As Double
Return Math.Sqrt(Math.Pow(point.x - x, 2) + Math.Pow(point.y - y, 2))
End Function
End Class
Class Point3D
Inherits Point2D
Public z As Double
Sub New(ByVal x As Double, ByVal y As Double, ByVal z As Double)
MyBase.New(x, y)
Me.z = z
End Sub
Function Distance2D(ByVal point As Point3D) As Double
Return MyBase.Distance(point)
End Function
Function Distance3D(ByVal point As Point3D) As Double
Return Math.Sqrt(Math.Pow(point.x - x, 2) +
Math.Pow(point.y - y, 2) +
Math.Pow(point.z - z, 2))
End Function
End Class
Module InheritanceMeMyBase
Sub Main()
Dim point1 As New Point2D(-5, -4)
Dim point2 As New Point2D(8, 3.5)
Console.WriteLine("Distance between (-5, -4) and (8, 3.5) = " &
point1.Distance(point2))
Dim point3 As New Point3D(1, 2, 5)
Dim point4 As New Point3D(-1, 0, -8)
Console.WriteLine("Distance between (1, 2, 5) and (-1, 0, -8) = " &
point3.Distance3D(point4))
Console.WriteLine("Distance between (1, 2, 5) and (-1, 0, -8) in 2D = " &
point3.Distance2D(point4))
Console.WriteLine("Distance between (1, 2, 5) and (-1, 0, -8) in 2D = " &
point3.Distance(point4))
End Sub
End Module
ในตัวอย่าง เป็นโปรแกรมในการหาระห่างระหว่างจุดสองจุดในสองมิติและสามมิติ เรามีสองคลาสคือ Point2D
เป็นคลาสสำหรับจุดในสองมิติ และ Point3D
เป็นคลาสสำหรับจุดในสามมิติ ซึ่งคลาสนี้ได้สืบทอดมาจากคลาส Point2D
Class Point2D
Public x As Double
Public y As Double
Sub New(ByVal x As Double, ByVal y As Double)
Me.x = x
Me.y = y
End Sub
Function Distance(ByVal point As Point2D) As Double
Return Math.Sqrt(Math.Pow(point.x - x, 2) + Math.Pow(point.y - y, 2))
End Function
End Class
นี่เป็นคลาสสำหรับจุดในสองมิติ ในคลาสมีตัวแปร x
และ y
สำหรับเก็บพิกัดของจุด ในคอนสรัตเตอร์ของคลาสเราได้ประกาศพารามิเตอร์ที่มีชื่อเหมือนกันกับตัวแปรของคลาส ดังนั้นในการเข้าถึงตัวแปรของคลาส เราจะใช้คำสั่ง Me
ตามด้วยจุดและชื่อของตัวแปรที่จะเข้าถึง ส่วนฟังก์ชัน Distance()
เป็นฟังก์ชันในการหาระยะห่างตามสูตรของพิกัดในสองมิติ ซึ่งนี่เป็นสิ่งที่เกี่ยวกับ variables scope ที่เราได้พูดถึงในส่วนสุดท้ายของบท Function Procedures II
Class Point3D
Inherits Point2D
Public z As Double
Sub New(ByVal x As Double, ByVal y As Double, ByVal z As Double)
MyBase.New(x, y)
Me.z = z
End Sub
Function Distance2D(ByVal point As Point3D) As Double
Return MyBase.Distance(point)
End Function
Function Distance3D(ByVal point As Point3D) As Double
Return Math.Sqrt(Math.Pow(point.x - x, 2) +
Math.Pow(point.y - y, 2) +
Math.Pow(point.z - z, 2))
End Function
End Class
นี่เป็นคลาสสำหรับจุดในสามมิติ คลาสนี้ได้สืบทอดจากคลาส Point2D
ในคอนสตรัคเตอร์เป็นการกำหนดค่าเริ่มต้นให้กับออบเจ็ค ในคำสั่ง MyBase.New(x, y)
เป็นการเรียกใช้คอนสตรัคเตอร์ของ base class นั้นจะใช้คำสั่ง MyBase
สำหรับการอ้างถึง
สำหรับคลาสนี้จะมีเมธอด Distance3D()
สำหรับหาระยะห่างของจุดในสามมิติ นอกจากนี้เรายังสร้างฟังก์ชัน Distance2D()
และเพราะว่ามันมีความหมายเหมือนกับฟังก์ชัน Distance()
เราใช้คำสั่ง MyBase
เพื่อเรียกเมธอดจาก base class ในความตั้งในของส่วนนี้เพื่อให้คุณรู้ว่าเราสามารถเข้าถึงสมาชิกของ base class ได้ทั้งหมด
Distance between (-5, -4) and (8, 3.5) = 15.0083310198036
Distance between (1, 2, 5) and (-1, 0, -8) = 13.3041346956501
Distance between (1, 2, 5) and (-1, 0, -8) in 2D = 2.82842712474619
Distance between (1, 2, 5) and (-1, 0, -8) in 2D = 2.82842712474619
นี่เป็นผลลัพธ์ของโปรแกรม ในสองบรรทัดสุดท้ายนั้นการเรียกเมธอด Distance2D() และ Distance() ในออบเจ็คของคลาส Point3D เป็นการทำงานเดียวกันซึ่งเป็นผลจากคำสั่ง MyBase
ในบทนี้ คุณได้เรียนรู้เกี่ยวกับการสืบทอดในภาษา Visual Basic การ Override method รวมถึงการใช้คำสั่ง Me และ MyBase เพื่อจัดการและเข้าถึงสมาชิกภายในคลาสและคลาสหลักของมัน