Virtual Function คืออะไร?
Virtual Function เป็นเมธอดที่ประกาศด้วยคีย์เวิร์ด virtual ใน Base Class เพื่อให้ Derived Class สามารถ Override (เขียนทับ) การทำงานได้ การเรียกใช้เมธอดจะถูกตัดสินใจในขณะ Runtime (Late Binding / Dynamic Dispatch)
Syntax
// Base Class
public virtual ReturnType MethodName(Parameters) {
// Base implementation
}
// Derived Class
public override ReturnType MethodName(Parameters) {
// New implementation
}
ตัวอย่างสมบูรณ์: Polymorphism ด้วย Virtual Functions
using System;
namespace PolymorphismApplication {
// Base Class
class Shape {
protected int Width, Height;
public Shape(int a = 0, int b = 0) {
Width = a;
Height = b;
}
// Virtual Method - สามารถ Override ได้
public virtual int Area() {
Console.WriteLine("Parent class area:");
return 0;
}
}
// Derived Class 1
class Rectangle : Shape {
public Rectangle(int a = 0, int b = 0) : base(a, b) { }
// Override เมธอด Virtual
public override int Area() {
Console.WriteLine("Rectangle class area:");
return Width * Height;
}
}
// Derived Class 2
class Triangle : Shape {
public Triangle(int a = 0, int b = 0) : base(a, b) { }
public override int Area() {
Console.WriteLine("Triangle class area:");
return (Width * Height / 2);
}
}
// Caller - ใช้ Polymorphism
class Caller {
public void CallArea(Shape sh) {
int a = sh.Area(); // Dynamic Dispatch - เรียกตาม Object จริง
Console.WriteLine("Area: {0}", a);
}
}
class Tester {
static void Main(string[] args) {
Caller c = new Caller();
Rectangle r = new Rectangle(10, 7);
Triangle t = new Triangle(10, 5);
c.CallArea(r); // เรียก Rectangle.Area()
c.CallArea(t); // เรียก Triangle.Area()
Console.ReadKey();
}
}
}
ผลลัพธ์
Rectangle class area:
Area: 70
Triangle class area:
Area: 25
กฎสำคัญของ Virtual Functions
- Base Class ต้องใช้
virtual - Derived Class ใช้
override(บังคับ) - Signature ต้องเหมือนกันทุกประการ (Return Type, Name, Parameters)
- Access Modifier ต้องเหมือนกัน (หรือเข้าถึงได้มากกว่า)
- ไม่สามารถเป็น
static,abstract, หรือsealedพร้อมกันได้
Virtual vs Abstract vs Non-Virtual
| ประเภท | คีย์เวิร์ด | Base Implementation | Derived ต้อง Override? | การเรียกใช้ |
|---|---|---|---|---|
| Virtual | virtual |
มี (Optional) | ไม่บังคับ | Dynamic Dispatch |
| Abstract | abstract |
ไม่มี (ห้ามมี Body) | บังคับ (ถ้า Derived ไม่ใช่ Abstract) | Dynamic Dispatch |
| Non-Virtual | (ไม่มีคีย์เวิร์ด) | มี | ไม่ได้ (ใช้ new แทน - Hiding) |
Static Binding |
เมื่อไหร่ควรใช้ Virtual?
- เมื่อต้องการให้ Derived Class เปลี่ยนพฤติกรรมได้
- เมื่อ Base Class มี Default Implementation ที่ใช้งานได้แล้ว
- เมื่อต้องการ Polymorphism (เรียกผ่าน Base Reference แต่ออกมาเป็น Derived Behavior)