Overloading Operators

ในบทนี้ คุณจะได้รู้จักและการใช้งานกับ Overloading Operators ในภาษา C# ซึ่งเป็นการเปลี่ยนการทำงานของตัวดำเนินการทางคณิตศาสตร์พื้นฐานให้สามารถทำงานกับออบเจ็คได้เหมือนกับการใช้งานกับประเภทข้อมูลพื้นฐาน (Primitive data type) ในภาษา C#

Overloading Operators คืออะไร

Overloading Operators คือการเปลี่ยนแปลงวิธีการทำงานของตัวดำเนินการทางคณิตศาสตร์ให้ทำงานตามที่ต้องการ ยกตัวอย่างเช่น ในการบวกเลขสองตัวนั้น เป็นการนำค่าของพวกมันมารวมกัน ซึ่งมันใช้ได้กับตัวเลข เช่น 2 + 3 = 5

แต่สำหรับข้อมูลแบบอื่นเช่น ต้องการเอาน้ำสองแก้วมารวมกัน ข้อมูลที่มีอาจจะเป็นรัศมีของแก้ว หรืออื่นๆ ถ้าหากแก้วนั้นเป็นเหมือนออบเจ็ค มันจึงทำให้การทำงานเมื่อนำมารวมกันนั้น ไม่ได้เป้นเหมือนตัวเลข แต่เราใช้เครื่องหมาย + เช่นเดิม ดังนั้น ในบทนี้คุณจะได้เรียนรู้เกี่ยวกับ Operator overloading กับออบเจ็ค ซึ่งเป็นความสามารถหนึ่งในภาษา C# ที่จะทำให้การทำงานกับออบเจ็คนั้นง่ายและรวดเร็วมากขึ้น

นี่เป็นรูปแบบของการทำ Overloading Operators ในภาษา C#

class MyClass
{
public static MyClass1 operator + (MyClass2 a, MyClass3 b)
{
MyClass c = b;
return c;
}
}

จากรูปแบบข้างบนนั้นเป็นการทำ Overloading operators สำหรับคลาส MyClass1 สำหรับเครื่องหมาย + (บวก) โดยสร้างฟังก์ชันภายในคลาสนั้นให้เป็น static เพราะว่าตัวดำเนินการนี้จะสามารถนำไปใช้กับออบเจ็คใดๆ ที่สร้างจากคลาสนี้ และใช้คำสั่ง operator ตามด้วยเครื่องหมายที่ทำการ Overload และส่งอากิวเมนต์สองตัวสำหรับ operand ทั้งสอง

การสร้างและการใช้ Overloading Operators

เพื่อให้คุณเข้าใจว่าทำไมเราจึงต้องทำ Operator overloading มาดูตัวอย่างต่อไปนี้

int a = 2;
int b = 3;
int c = a + b;
int d = a - b;

ในตัวอย่าง เรามีตัวแปร a และ b และได้กำหนดค่าให้กับตัวแปรเหล่านั้น หลังจากนั้นเราหาผลรวมโดยการใช้ตัวดำเนินการ + และหาผลต่างโดยการใช้ตัวดำเนินการ - ซึ่งตัวดำเนินการเหล่านี้สามารถใช้ได้กับ Primitive data type อยู่แล้ว แต่การ Operator overloading นั้นจะทำให้เราสามารถใช้ตัวดำเนินการได้กับออบเจ็ค ตามความหมายที่เรากำหนดขึ้น

ต่อไปมาดูตัวอย่างการใช้งาน Operator overloading ในภาษา C# ซึ่งจะเป็นโปรแกรมในการหาผมรวม ผลต่าง และระยะหว่าง ระหว่างจุดสองมิติ โดยการใช้ตัวดำเนินการที่ได้จากการทำ Operator overloading

using System;

class OperatorOverloading
{
static void Main(string[] args)
{
Vector2D vector1 = new Vector2D(2, 3);
Vector2D vector2 = new Vector2D(-1, 5);

Vector2D add = vector1 + vector2;
Vector2D subtract = vector1 - vector2;
double distance = vector1 / vector2;

Console.WriteLine("Vector 1 " + vector1.GetPoint());
Console.WriteLine("Vector 2 " + vector1.GetPoint());
Console.WriteLine("Add vector " + add.GetPoint());
Console.WriteLine("Subtract vector " + subtract.GetPoint());
Console.WriteLine("Distance " + distance);
}
}

class Vector2D
{

public int x;
public int y;

public Vector2D(int x, int y)
{
this.x = x;
this.y = y;
}

public string GetPoint()
{
return "[" + x + ", " + y + "]";
}

public static Vector2D operator +(Vector2D a, Vector2D b)
{
int x = a.x + b.x;
int y = a.y + b.y;
Vector2D c = new Vector2D(x, y);
return c;
}

public static Vector2D operator -(Vector2D a, Vector2D b)
{
int x = a.x - b.x;
int y = a.y - b.y;
Vector2D c = new Vector2D(x, y);
return c;
}

public static double operator /(Vector2D a, Vector2D b)
{
double x = Math.Pow(a.y - a.x, 2) + Math.Pow(b.y - b.x, 2);
return Math.Sqrt(x);
}
}

ในตัวอย่าง เป็นโปรแกรมในการทำงานกับ Vector 2 มิติ เราได้สร้างคลาส Vector2D สำหรับเก็บข้อมูลของจุดในสองมิติ และเมธอด GetPoint() เป็นเมธอดในการรับค่าของจุด

public static Vector2D operator +(Vector2D a, Vector2D b)
{
int x = a.x + b.x;
int y = a.y + b.y;
Vector2D c = new Vector2D(x, y);
return c;
}

public static Vector2D operator -(Vector2D a, Vector2D b)
{
int x = a.x - b.x;
int y = a.y - b.y;
Vector2D c = new Vector2D(x, y);
return c;
}

ภายในคลาส Vector2D เราได้ทำการ overload ตัวดำเนินการบวก + สำหรับบวกค่าของสอง Vector ออบเจ็ค a กับ bเข้าด้วยกันที่เป็นพารามิเตอร์ และส่งค่ากลับเป็น Vector ใหม่ที่มีการรวม Vector แล้ว และสำหรับตัวดำเนินการลบ - เช่นกัน เป็นการหักล้างสอง Vector และได้ผลลัพธ์เป็นผลต่างระหว่าง Vector a กับ b

public static double operator /(Vector2D a, Vector2D b)
{
double x = Math.Pow(a.y - a.x, 2) + Math.Pow(b.y - b.x, 2);
return Math.Sqrt(x);
}

และทำการ overload ตัวดำเนินการหาร / สำหรับการหาระยะห่างของจุดของแรงของ Vector ในสองมิติ จากสูตรของมัน นั่นหมายความ่า เราได้เปลี่ยนการกระทำของตัวดำเนินการ / ไปแล้ว เมื่อมันใช้กับออบเจ็คของ Vector2D

Vector 1 [2, 3]
Vector 2 [2, 3]
Add vector [1, 8]
Subtract vector [3, -2]
Distance 6.08276253029822

นี่เป็นผลลัพธ์การทำงานของโปรแกรมสำหรับ Operator overloading ในภาษา C# คุณจะเห็นว่าเราสามารถใช้ตัวดำเนินการต่างๆ กับออบเจ็คที่สร้างขึ้นตามการทำงานที่เรากำหนด ซึ่งทำให้การเขียนโปรแกรมของเราสะดวกและง่ายขึ้นเป็นอย่างมาก

Operator overloading example

ต่อมาเป็นตัวอย่างเพิ่มเติมสำหรับ Operator overloading ในภาษา C# ในตัวอย่างนี้ เราจะขอยกตัวอย่างสำหรับการหาผลรวมน้ำในแก้วน้ำ โดยเราจะสร้างคลาสของแก้วน้ำขึ้นมา

using System;

namespace OverloadingOperators
{
class Program
{
static void Main(string[] args)
{
Glass g1 = new Glass(5.2f, 8);
Glass g2 = new Glass(3.2f, 10);

float totalvolume = g1 + g2;
Console.WriteLine("g1 and g2 sumation of volume = " + totalvolume);
}
}
}

class Glass
{
const float PI = 3.14F;

private float radius;
private float height;

public Glass (float r, float h)
{
radius = r;
height = h;
}

public static float operator +(Glass a, Glass b)
{
float totalvolume = a.GetVolume() + b.GetVolume();
return totalvolume;
}

public float GetVolume()
{
return (2 * radius * 3.14f) * height;
}
}

ในตัวอย่างเป็นการหาผลรวม ของออบเจ็คที่สร้างจากคลาส Glass และมีค่า return เป็น float โดยในคำสั่ง g1 + g2 นั้นเป็นการทำงานจากการ overloading และมเื่อรันโปรแกรมจะได้ผลลัพธ์ดังข้างล่าง

g1 and g2 sumation of volume = 462.208

เพื่อให้เข้าใจมากขึ้น การทำ overloading operators นั้นคล้ายกันกับ overloading method แต่สิ่งที่ต่างกันคือในการ return ค่าต้องเลือกสำหรับค่าใดค่าหนึ่งเท่านั้น ตัวอย่างต่อไปแทนที่เราส่งค่าผลรมของปริมาตรของแก้วทั้งสองกลับ เราจะทำการส่งแก้วใบใหม่ที่มีปริมาตรเท่าเดิมแทน

using System;

namespace OverloadingOperators
{
class Program
{
static void Main(string[] args)
{
Glass g1 = new Glass(5.2f, 8);
Glass g2 = new Glass(3.2f, 10);

Glass g3 = g1 + g2;
Console.WriteLine("g3 radius = " + g3.radius);
Console.WriteLine("g3 height = " + g3.radius);
Console.WriteLine("g3 volume = " + g3.GetVolume());
}
}
}

class Glass
{
const float PI = 3.14F;

public float radius;
public float height;

public Glass (float r, float h)
{
radius = r;
height = h;
}

public static Glass operator +(Glass a, Glass b)
{
float totalvolume = a.GetVolume() + b.GetVolume();
float totalArea = a.GetBaseArea() + b.GetBaseArea();

float newRadius = totalArea / 2 / PI;
float newHeight = totalvolume / totalArea;
Glass c = new Glass(newRadius, newHeight);
return c;
}

public float GetBaseArea()
{
return 2 * radius * PI;
}

public float GetVolume()
{
return (2 * radius * PI) * height;
}
}

ในตัวอย่าง นั้นเป็นการสร้าง overloading operators สำหรับออบเจ็คจากคลาส Glass เช่นเดิม แต่ตอนนี้ค่าที่ส่งกลับจำเป็นออบเจ็คของ Glass เช่นเดิม ที่มีปริมาตรเท่าเดิม และนี่เป็นผลลัพธ์เมื่อรันโปรแกรม

g3 radius = 8.4
g3 height = 8.4
g3 volume = 462.208

จากผลของโปรแกรมั้นเราได้ทำการเปลี่ยนให้เครื่องหมาย + สำหรับออบเจ็คของ Glass นั้น return ออบเจ็คของ Glass อันใหม่ ที่มีปริมาตรเท่าเดิม และมีรัศมีและความสูงใหม่เป็นอย่างที่เห็น

Overloadable operators

ในภาษา C# ส่วนมากแล้วตัวดำเนินการเกือบทุกชนิดสามารถที่ทำการ Operator overloading ได้โดยแต่ละตัวดำเนินการนั้นจะมีจำนวนของ Operand ที่แตกต่างกัน ตารางข้างล่างเป็นตัวดำเนินการที่สามารถทำการ Operator overloading ได้ในภาษา C#

OperatorsNumber of operand
+1 or 2
-1 or 2
!1
~1
++1
--1
*2
/2
%2
==2
!=2
<2
>2
<=2
>=2

ตัวอย่างของการ Operator overloading ในการใช้งานตัวดำเนินการต่างๆ

public static SomeObjectA operator - (SomeObjectB a, SomeObjectC b)
{
// do something
return ...; // SomeObjectA
}

public static bool operator == (SomeObjectB a, SomeObjectC b)
{
// do something
return ...; // bool value
}

public static SomeObjectA operator ++ (SomeObjectB a)
{
// do something
return ...; // SomeObjectA
}

ในตัวอย่าง เป็นรูปแบบการใช้งาน Operator overloading กับตัวดำเนินการต่างๆ ซึ่งอาจจะเป็นหนึ่งหรือสอง Operands และสำหรับการส่งค่ากลับนั้นสามารถเป็นออบเจ็คหรือ Primitive data type ก็ได้

ในบทนี้ คุณได้รู้จักและได้รู้การสร้างและการใช้งาน Overloading operators ในภาษา C# เพื่อให้การทำงานเป็นไปตามที่ต้องการได้ และมันเป็นสิ่งที่อำนวยความสะดวกในการจัดการกับออบเจ็คที่เราสร้างขึ้นมาเป็นอย่างมาก


บทความเกี่ยวกับ Overloading Operators

ตัวดำเนินการ ในภาษา C

ตัวดำเนินการจะถูกใช้กับตัวแปรและค่าคงที่ในการดำเนินการบางอย่าง เช่น การดำเนินการทางคณิตศาสตร์ ในภาษา C มีตัวดำเนินการประเภทต่างๆ ที่ทำหน้าที่แตกต่างกันไป ในบทนี...

ตัวดำเนินการ ในภาษา Java

ในบทนี้ คุณจะได้เรียนรู้เกี่ยวกับตัวดำเนินการในภาษา Java และการใช้งานตัวดำเนินการ ในภาษา Java มีตัวดำเนินการประเภทต่างๆ ดังนี้ String concatenating operator หรื...

ตัวดำเนินการ ในภาษา Visual Basic

ตัวดำเนินการ ใช้สำหรับจัดการกับตัวแปรและค่าคงที่ ยกตัวอย่างเช่น การกำหนดค่า การเปรียบเทียบข้อมูล ตัวดำเนินการในภาษา Visual Basic นั้นมีหลายรูปแบบ นี่เป็นตัวดำเน...

ตัวดำเนินการ ในภาษา C++

ในบทนี้ คุณจะได้เรียนรู้เกี่ยวกับตัวดำเนินการ (Operator) ในภาษา C++ ตัวดำเนินการถูกใช้เพื่อดำเนินการกับตัวแปรและค่าคงที่สำหรับการสร้าง Expression เพื่อทำงานโปรแ...

ตัวดำเนินการ ในภาษา Python

ตัวดำเนินการ (Operators) คือกลุ่มของเครื่องหมายหรือสัญลักษณ์ที่ใช้ทำงานเหมือนกับฟังก์ชัน แต่แตกต่างกันตรงไวยากรณ์หรือความหมายในการใช้งาน ในภาษา Python นั้นสนับส...