---
description: ศศิพร โพธิ์ชะคุ้ม 650710582
---

# Invoking an overloaded constructure using this keyword



การใช้คีย์เวิร์ด this เรียก constructor ที่ถูก overloaded ช่วยให้การจัดการและสร้างอ็อบเจ็กต์ภายในคลาสเดียวกันมีความยืดหยุ่นและมีประสิทธิภาพมากขึ้นทั้งลดความซับซ้อนในการทำซ้ำโค้ด ทำให้เข้าใจได้ง่ายยิ่งขึ้น

## ข้อสำคัญของการใช้ this <a href="#this" id="this"></a>

* คอนสตรัคเตอร์ที่ถูกเรียกด้วย this ต้องอยู่ใน class เดียวกันเสมอ
* สามารถส่งพารามิเตอร์ให้กับคอนสตรัคเตอร์ที่ถูกเรียกได้
* ชี้ไปที่สมาชิกของคลาสที่ถูกใช้งานอยู่เสมอ หรือก็คืออินสแตนซ์ของคลาสที่เราใช้งานในขณะนั้น
* เป็นตัวบอก compiler ให้เรียกใช้ คอนสตรัคเตอร์เริ่มต้น(default constructor) หรือ constructor คอนสตรัคเตอร์ที่ไม่มีอาร์กิวเมนต์

## การเรียกคอนสตรัคเตอร์ด้วย this <a href="#this-1" id="this-1"></a>

* คอนสตรัคเตอร์สามารถเรียกใช้อีกคอนสตรัคเตอร์หนึ่งในออบเจ็กต์เดียวกันได้ โดยใช้คำสั่ง `this` ซึ่งสามารถใช้งานได้ทั้งคอนสตรัคเตอร์มีพารามิเตอร์และไม่มีพารามิเตอร์(default constructor)
* พารามิเตอร์ในคอนสตรัคเตอร์จะสามารถใช้เป็นพารามิเตอร์สำหรับ `this` หรือใช้ในนิพจน์ (expression) ก็ได้

## Syntax <a href="#syntax" id="syntax"></a>

```csharp
class X 
{
   public X: this()
   {
      // โค้ด..
   }
}
```

## ตัวอย่างโปรแกรม <a href="#undefined" id="undefined"></a>

### ตัวอย่างที่ 1 <a href="#undefined-1" id="undefined-1"></a>

```csharp
// C# program to illustrate how to invoke
// overloaded constructor using this keyword
using System;
class Geek {

	// Constructor without parameter(default constructor)
	public Geek()
	{
		Console.WriteLine("Hello! Constructor 1");
	}

	// Constructor with parameter
	// Here this keyword is used 
	// to call Geek constructor
	public Geek(int a) 
	: this()
	{
		Console.WriteLine("Hello! Constructor 2");
	}
}

// Driver Class
public class GFG {

	// Main method
	static public void Main()
	{

		// Create object of Geek class
		Geek obj = new Geek(2);
	}
}

```

ในตัวอย่างนี้ จะเห็นได้ว่าคลาส Geek มีคอนสตรัคเตอร์ อยู่ 2 ตัว คือ

1. Geek() ไม่มีพารามิเตอร์ โดยคอนสตรัคเตอร์นี้จะถูกเรียกเมื่อสร้างอ็อบเจ็กต์ `Geek` โดยไม่มีการส่งพารามิเตอร์เข้าไป
2. Geek(int a) มีพารามิเตอร์ 1 ตัว คือ `int a`โดยคอนสตรัคเตอร์นี้มีการเรียกใช้ `this()` เพื่อเรียกคอนสตรัคเตอร์ที่ไม่มีพารามิเตอร์ก่อนที่จะทำงานในบล็อกนี้ ซึ่งจะทำให้ข้อความ "Hello! Constructor 1" ถูกพิมพ์ออกมาก่อน

ในคลาส CFG ซึ่งทำหน้าที่เป็น main ของโปรแกรม จะเห็นได้ว่า

เป็นการสร้างอ็อบเจ็กต์ที่เรียกคอนสตรัคเตอร์ที่มีพารามิเตอร์ นั่นคือ Geek(int a) จะถูกเรียกใช้ ซึ่งการที่จะมีการทำงานในส่วนของคอนสตรัคเตอร์นี้ จะมีการเรียกใช้คอนสตรัคเตอร์ที่ไม่มีพารามิเตอร์ นั่นคือ Geek() โดยการเรียกคอนสตรัคเตอร์นี้ผ่าน this() ซึ่งจะทำให้ "Hello! Constructor 1" ถูกพิมพ์ออกมา แล้วจึงจะทำงานในบล็อกของคอนสตรัคเตอร์ของตนเอง และพิมพ์ "Hello! Constructor 2"

#### output <a href="#output" id="output"></a>

```
Hello! Constructor 1
Hello! Constructor 2
```

### ตัวอย่างที่ 2 <a href="#id-2" id="id-2"></a>

```csharp
public Employee(int weeklySalary, int numberOfWeeks)
    : this(weeklySalary * numberOfWeeks)
{
}
public Employee(int annualSalary)
{
    Salary = annualSalary;
}
```

จากตัวอย่างนี้ มีการใช้ this เรียกคอนสตรัคเตอร์ที่สอง โดยคอนสตรัคเตอร์แรก ที่มีพารามิเตอร์ 2 ตัว ได้แก่ int weeklySalary และ int numberOfWeeks ซึ่งในคอนสตรัคเตอร์ที่2มี พารามิเตอร์ 1 ตัว จะทำการรับ weeklySalary\*numberOfWeeks เข้ามาเป็นค่าพารามิเตอร์ของตัวเองและเมื่อมีการสร้างออบเจ็กต์ในคลาส main

```csharp
public class Example {

	// Main method
	static public void Main()
	{

		// Create object of Employee class
		Employee obj = new Employee(5000,4);
	}
}
```

เป็นการสร้างอ็อบเจ็กต์ที่เรียกคอนสตรัคเตอร์ที่มีพารามิเตอร์ นั่นคือ Employee(int weeklySalary, int numberOfWeeks) เมื่อทั้งสองรับค่าพารามิเตอร์ 5000 และ 4 เข้าไปแล้ว ก็จะทำการเรียกใช้ Employee(int annualSalary) โดยใช้ this ซึ่งมีการส่งพารามิเตอร์ไป 1 ตัวคือ ค่า weeklySalary\*numberOfWeeks นั่นคือ 20000 ไปยังคอนสตรัคเตอร์ตตัวที่สอง ทำให้ Salary ในคอนสตรัคเตอร์ที่สอง มีค่าเป็น 20000



## เปรียบเทียบกับ Python <a href="#python" id="python"></a>

### สิ่งที่คล้ายกับการใช้คีย์เวิร์ด this ใน c# <a href="#this-c" id="this-c"></a>

* การใช้ self จะคล้ายกับการใช้ this ในแง่ของการอ้างอิงถึง Instance ปัจจุบันของคลาส
* การสร้างและการกำหนดค่าตอนสร้าง instance ซึ่งใน C# เราสามารถ overload constructor เพื่อเรียกใช้ constructure อื่น ในอีก constructure ที่อยู่ในคลาสเดียวกัน ซึ่งคล้ายกับการที่ Python มี \_\_init\_\_()ที่กำหนดค่าตอนสร้าง instance ซึ่งจะใช้วิธีจัดการกับพารามิเตอร์ใน \_\_init\_\_() โดยตรงแทนการ overload constructure

### สิ่งที่แตกต่างกัน <a href="#undefined-2" id="undefined-2"></a>

* Python ไม่มีการ overload constructor เหมือนใน C# แต่ใช้การจัดการพารามิเตอร์และเงื่อนไขใน `__init__()` เพื่อจำลองพฤติกรรมเดียวกันได้
* การใช้ this ใน C# สามารถใช้เรียก constructor อื่นภายใน class เดียวกันได้ แต่ใน Python ใช้การสร้างเมธอดแยกออกมาต่างหาก หรือการจัดการค่าภายใน \_\_**init**()\_\_ แทน

### **ตัวอย่างการใช้ \_\_init\_\_()จำลองพฤติกรรมเดียวกัน**

```python
class Dog:
    def __init__(self, name, age=None):
        self.name = name
        if age is not None:
            self.age = age
        else:
            self.age = "Unknown"

    def __str__(self):
        return f"{self.name} is {self.age} years old"
        

#ทำการสร้างออบเจ็กต์และแสดงผล
>>> d1 = Dog("Fido", 5) # สร้างออบเจ็กต์ d1 ชื่อ "Fido" และอายุ 5
>>> print(d1)

>>> d2 = Dog("Buddy") # สร้างออบเจ็กต์ d2 ชื่อ "Buddy" และไม่กำหนดอายุ
>>> print(d2)

```

จากตัวอย่างจะเห็นได้ว่า \_\_init\_\_() เป็นเมธอดที่จะถูกเรียกใช้เมื่อมีการสร้างออบเจ็กต์ของคลาส Dog ซึ่งมีพารามิเตอร์ ได้แก่ self, name และ age โดยเรามีการกำหนดค่าเริ่มต้นของ age ไว้ให้เป็น None ทำให้สามารถสร้างอ็อบเจ็กต์ได้หลากหลายเช่นเดียวกับการ overload constructors ใน C# ซึ่งการใช้ default argument นี้ คล้ายกับการใช้ this ในC# ซึ่งเราสามารถปรับความยืดหยุ่นของการส่งพารามิเตอร์ตอนสร้างออบเจ็กต์ได้ ถ้าเรากำหนดต่า age ก็จะเก็บค่าที่เรากำหนดไว้ในฟิลด์ self.age ถ้าไม่กำหนด ก็จะเป็น Unknown

#### **Output**

```
Fido is 5 years old
Buddy is Unknown years old
```



## เปรียบเทียบกับ Java <a href="#java" id="java"></a>

ใน Java เราสามารถใช้ this ได้เหมือนๆกันกับ C# โดยระหว่างการoverloading คอนสตรัคเตอร์ จะใช้ this ในการเรียกคอนสตรัคเตอร์ที่ไม่มีพารามิเตอร์ (default constructure) โดยอัตโนมัติจากคอนสตรัคเตอร์ที่มีพารามิเตอร์

### ตัวอย่างการใช้ `this` เป็นอาร์กิวเมนต์ในคอนสตรัคเตอร์ <a href="#this-2" id="this-2"></a>

```java
// Java program to illustrate role of this() in
// Constructor Overloading
public class Box {
	double width, height, depth;
	int boxNo;

	// constructor used when all dimensions and
	// boxNo specified
	Box(double w, double h, double d, int num)
	{
		width = w;
		height = h;
		depth = d;
		boxNo = num;
	}

	// constructor used when no dimensions specified
	Box()
	{
		// an empty box
		width = height = depth = 0;
	}

	// constructor used when only boxNo specified
	Box(int num)
	{
		// this() is used for calling the default
		// constructor from parameterized constructor
		this();

		boxNo = num;
	}

	public static void main(String[] args)
	{
		// create box using only boxNo
		Box box1 = new Box(1);

		// getting initial width of box1
		System.out.println(box1.width);
	}
}
```

#### จากตัวอย่างจะเห็นได้ว่า <a href="#undefined-3" id="undefined-3"></a>

**Class Box มี คอนสตรัคเตอร์อยู่ 3 ตัว**

* คอนสตรัคเตอร์ที่มีพารามิเตอร์ ได้แก่ Box(double w, double h, double d, int num) ใช้กำหนดความกว้าง, ความสูง, ความลึก, และหมายเลขกล่องทั้งหมด
* คอนสตรัคเตอร์ที่ไม่มีพารามิเตอร์ ได้แก่ Box() ที่เป็นกล่องเปล่า (width, height และ dept มีค่าเป็น 0)
* คอนสตรัคเตอร์ Box(int num) มีการเรียกใช้งานคอนสตรัคเตอร์ที่ไม่มีพารามิเตอร์ ด้วยคำสั่ง this() เพื่อให้ออบเจ็กต์ที่สร้างมีค่า width, height และ dept เป็น 0 ก่อนที่จะตั้งค่าหมายเลขกล่อง.

#### Main

* ในส่วนของ main จะมีการสร้างอ็อบเจ็กต์ Box box1 = new Box(1); ซึ่งจะทำการเรียกคอนสตรัคเตอร์ที่มีพารามิเตอร์ 1 ตัว คือ Box(int num) ซึ่งใช้ this() เพื่อเรียกคอนสตรัคเตอร์ที่ไม่มีพารามิเตอร์ก่อน นั่นคือ Box() เพื่อให้แน่ใจว่าค่าต่างๆถูก set เป็นกล่องเปล่าเมื่อรันโปรแกรมก็จะได้ output ดังนี้

```
0.0
```



## เปรียบเทียบกับภาษา C <a href="#c" id="c"></a>

ในภาษา C นั้นไม่มีแนวคิดของ **constructor** แบบเดียวกับที่มีใน C# เพราะภาษา C เป็นภาษาเชิงโครงสร้าง (procedural programming language) ซึ่งไม่ได้รองรับการเขียนโปรแกรมเชิงวัตถุ (OOP) โดยตรงแนวคิดเกี่ยวกับการเรียกใช้ overloaded constructor หรือการใช้ this จึงไม่มีอยู่ในภาษา C



## เปรียบเทียบกับ C++ <a href="#c-1" id="c-1"></a>

ใน C++ **constructor delegation** ช่วยให้ constructor หนึ่งสามารถเรียก constructor อื่นภายในคลาสเดียวกันได้ ซึ่งจะช่วยหลีกเลี่ยงการเขียนโค้ดซ้ำซ้อน ทำให้โค้ดสะอาดและดูแลรักษาง่ายขึ้น คล้ายกับการใช้ this ในการเรียก overloaded constructor

### ตัวอย่างโปรแกรม <a href="#undefined-4" id="undefined-4"></a>

```cpp
// Program to demonstrate constructor delegation
// in C++
#include <iostream>
using namespace std;
class A {
	int x, y, z;

public:
	A()
	{
		x = 0;
		y = 0;
		z = 0;
	}

	// Constructor delegation 
	A(int z) : A()
	{
		this->z = z; // Only update z
	}

	void show()
	{
		cout << x << '\n'
			<< y << '\n'
			<< z;
	}
};
int main()
{
	A obj(3);
	obj.show();
	return 0;
}
```

จากตัวอย่างจะเห็นได้ว่า คลาสนี้มีคอนสตรัคเตอร์อยู่สองตัว คือ Constructor A(): กำหนดค่าเริ่มต้นให้ตัวแปร x, y, และ z เป็น 0. และ Constructor ที่ใช้การ delegation A(int z) ซึ่งจะทำการเรียก A() ผ่านการใช้ `: A()` ก่อนที่จะทำการกำหนดค่า z ด้วยค่าที่ได้รับจากพารามิเตอร์

### **การทำงานของโปรแกรม**

เมื่อเราเรียก `A obj(3);` จะทำการเรียก constructor ที่รับพารามิเตอร์ คือ `A(int z)` ซึ่ง constructor นี้จะเรียก `A()` ผ่านการใช้ `: A()` เพื่อกำหนดค่าเริ่มต้นให้ตัวแปร `x`, `y`, และ `z` เป็น 0 จากนั้นจึงจะอัพเดทค่าของ z เป็น 3 และเรียก `obj.show();` แสดงค่าของ `x`, `y`, และ `z`

#### Output

```
0
0
3
```

## Video <a href="#video" id="video"></a>

{% embed url="https://youtu.be/8qcANTTvgAA" %}

## Presentation <a href="#presentation" id="presentation"></a>

{% file src="https://2358863655-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FFPtNVavcFSOLzLOmmCgv%2Fuploads%2F78dPomzdr55a5OBtUDzQ%2FInvoking%20an%20overloaded%20constructor%20using%20this%20keyword.pptx?alt=media&token=c716f5b2-f803-4374-b7e2-ad2b8b03ef82" %}

## อ้างอิง <a href="#undefined-6" id="undefined-6"></a>

* GeeksforGeeks, (27 August 2021), ข้อสำคัญของการใช้ this ,Syntax และตัวอย่างโปรแกรม ตัวอย่างที่1 [https://www.geeksforgeeks.org/invoking-an-overloaded-constructor-using-this-keyword-in-c-sharp/](https://www.geeksforgeeks.org/invoking-an-overloaded-constructor-using-this-keyword-in-c-sharp/)
* Microsoft,(3 December 2024), ตัวอย่างโปรแกรม ตัวอย่างที่2 ,การเรียกคอนสตรัคเตอร์ด้วย this,[https://learn.microsoft.com/en-us/dotnet/csharp/programming-guide/classes-and-structs/using-constructors](https://learn.microsoft.com/en-us/dotnet/csharp/programming-guide/classes-and-structs/using-constructors)
* David Amos, (2023),เปรียบเทียบกับPython[https://realpython.com/python3-object-oriented-programming/#reader-comments](https://realpython.com/python3-object-oriented-programming/#reader-comments)
* Python Software Foundation,(11 October 2024),ตัวอย่างการใช้\_\_init\_\_(),[https://docs.python.org/3/tutorial/classes.html](https://docs.python.org/3/tutorial/classes.html)
* GeeksforGeeks,(16 Jun 2023),เปรียบเทียบกับ Java,[https://www.geeksforgeeks.org/constructor-overloading-java/](https://www.geeksforgeeks.org/constructor-overloading-java/)
* GGeeksforGeeks,(23 Jul, 2021),เปรียบเทียบกับ C++,[https://www.geeksforgeeks.org/constructor-delegation-c/](https://www.geeksforgeeks.org/constructor-delegation-c/)
