Inheritance in Constructors

เขียนโดย นางสาวสุชาวดี ตู้สมบัติ 650710590

Inheritance เป็นคุณสมบัติที่สำคัญของโปรแกรมภาษาเชิงวัตถุ (object-oriented programming) ที่ทำให้การสร้างคลาสใหม่ ไม่ต้องเขียนซ้ำซ้อนกับคลาสเดิม แต่จะสืบทอดเอาคุณสมบัติและพฤติกรรมของคลาสเดิมมาได้ เช่น เมธอด และ ฟิลล์ ยกเว้น Constructor ไม่ได้สืบทอดโดยตรง แต่เราสามารถเรียก constructor ของคลาสแม่/คลาสฐาน (base class) จาก คลาสลูก/คลาสที่สืบทอด(derived class)ได้ โดยใช้คีเวิร์ด base

example

C#
class Person
{
    public string Name { get; set; }
    public int Age { get; set; }

    public Person(string name, int age)
    {
        Name = name;
        Age = age;
    }
}

class Employee : Person
{
    public int EmployeeId { get; set; }

    public Employee(string name, int age, int employeeId) : base(name, age)
    {
        EmployeeId = employeeId;
    }
}

จากตัวอย่างข้างต้น Person เป็น base class และ Employee เป็น derived class ซึ่ง constructor ของคลาส Person มีพารามิเตอร์ คือ name และ age ซึ่งเป็นกำหนดค่าเริ่มต้นให้กับฟิลล์ Name และ Age คลาส Employee สืบทอด คลาส Person มาและประกาศ constructor ที่มีพารามิเตอร์ ได้แก่ name , age และ employeeId ซึ่ง มีการเรียก constructor ของ Person โดยใช้คำว่า :base(name, age) เพื่อดึง พารามิเตอร์ name และ age มาใช้นั่นเอง

ตัวอย่างการใช้งาน

C#
class Program
{
    static void Main(string[] args)
    {
        Employee emp = new Employee("Somying", 25, 12345);
        Console.WriteLine($"Name: {emp.Name}, Age: {emp.Age}, 
        EmployeeId: {emp.EmployeeId}");
    }
}

output

Name: Somying, Age: 25, EmployeeId: 12345

การใช้ constructor มี 2 กรณีที่น่าพิจารณา ได้แก่

  • กรณีที่ 1 คลาสลูกมี constructor คลาสแม่ไม่มี constructor ที่เรากำหนดขึ้นมา มันจึงเรียกใช้ default constructor โดยอัตโนมัติ

example

C#
using System;
class Tank {
	double t_radius;
	double t_height;
	public double Radius{
		get { return t_radius; }
		set {t_radius = value < 0 ? -value : value;}
	}
	public double Height{
		get { return t_height; }
		set { t_height = value < 0 ? -value : value; }
	}
	public void DisplayDimension(){
		Console.WriteLine("The radius of tank is :" + Radius 
				+ " and the height of tank is :" + Height);
	}
}

class AreaOfTank : Tank {
	string Color;
	// Constructor
	public AreaOfTank(string c, double r, double h){
		// from base class
		Radius = r;
		Height = h;
		// from derived class
		Color = c;
	}
	public double Area(){
		return 2 * 3.14 * Radius * Height;
	}
	public void DisplayColor(){
		Console.WriteLine("The Color of tank is " + Color);
	}
}

class GFG {
	static void Main(){
		AreaOfTank t1 = new AreaOfTank("Green", 6.0, 12.0);
		t1.DisplayColor();
		t1.DisplayDimension();
		Console.WriteLine("Area is " + t1.Area());
	}
}

จากตัวอย่างข้างต้น คลาส Tank เป็น base class ให้ข้อมูลเกี่ยวกับขนาดถัง ส่วนคลาส AreaOfTank เป็น derived class ใช้เพิ่มข้อมูลสีและคำนวณพื้นที่ของถึง คลาส Tank ไม่มี constructor ที่กำหนดเอง จึงใช้ default constructor สำหรับสร้างวัตถุของคลาสนี้ และในคลาส AreaOfTank จะมี constructor ที่กำหนดเอง สำหรับสร้างวัตถุของคลาสนี้

  • กรณีที่ 2 คลาสแม่และคลาสลูกต่างมี constructor ของตัวเอง constructor ของทั้งสองคลาสจึงถูกเรียกใช้งาน ผ่านคำสั่ง base เพื่อเรียก constructor ของคลาสแม่จากภายใน constructor ของคลาสลูก

example

using System;
class Tank {
	double t_radius;
	double t_height;
	// Constructor for Tank
	public Tank(double r, double h){
		Radius = r;
		Height = h;
	}
	public double Radius{
		get { return t_radius; }
		set { t_radius = value < 0 ? -value : value; }
	}

	public double Height{
		get { return t_height; }
		set { t_height = value < 0 ? -value : value; }
	}
	public void DisplayDimension(){
		Console.WriteLine("The radius of tank is :" + Radius 
				+ " and the height of tank is :" + Height);
	}
}

class AreaOfTank : Tank {
	string Color;
	// Call the Constructor of the 
	// base class, i.e Tank
	// Using base keyword
	public AreaOfTank(string c, double r, double h) : base(r, h){
		Color = c;
	}
	public double Area(){
		return 2 * 3.14 * Radius * Height;
	}
	public void DisplayColor(){
		Console.WriteLine("The Color of tank is " + Color);
	}
}

class GFG {
	static void Main(){
		AreaOfTank t1 = new AreaOfTank("Brown", 4.0, 8.0);
		t1.DisplayColor();
		t1.DisplayDimension();
		Console.WriteLine("Area is " + t1.Area());
	}
}

จากตัวอย่างข้างต้น มีbase class และ derived class อันเดียวกับกรณีที่1 แต่ คลาส Tank มี constructor ที่เรากำหนดขึ้นมา ซึ่งมีตัวแปร Radius และ Height และ คลาส AreaOfTank มีการอธิบายสีและพื้นที่ของถัง ดังนั้น constructor ของ คลาส AreaOfTank จึงเรียก constructor ของคลาส Tank โดยส่งพารามิเตอร์ r และ h เข้าไป เพื่อกำหนดค่า Radius และ Height มาใช้ใน คลาส AreaOfTank โดยที่มันไม่ต้องกำหนดค่าเหล่านี้เองอีก

สรุป การใช้ คีย์เวิร์ด base ทำให้การกำหนดค่าในกับ object ของคลาสแม่ทำได้ง่าย และช่วยให้การเรียก constructor ของคลาสแม่จากคลาสลูก ช่วยประหยัดเวลาไม่ต้องเขียนโค้ดซ้ำ


เปรียบเทียบกับภาษา Java/C++/Python

Java

java เรียก คลาสแม่ว่า superclass และเรียกคลาสลูกว่า subclass มีการเรียกใช้ constructor ของคลาสแม่ คล้ายกับ C# แต่จะใช้คำว่า super() ซึ่งใน C# คือคำว่า base() แต่ถ้าไม่ได้เรียก super() มันจะเรียกใช้ default constructor ของคลาสแม่โดยอัตโนมัติ และ การสืบทอดใน java จะใช้คำว่า extends

example

java
// super keyword with constructor 
// superclass Person 
class Person { 
	Person() 
	{ 
		System.out.println("Person class Constructor"); 
	} 
} 

// subclass Student extending the Person class 
class Student extends Person { 
	Student() 
	{ 
		// invoke or call parent class constructor 
		super(); 

		System.out.println("Student class Constructor"); 
	} 
} 

// Driver Program 
class Test { 
	public static void main(String[] args) 
	{ 
		Student s = new Student(); 
	} 
}

output

Person class Constructor
Student class Constructor

จากตัวอย่างข้างต้น มีคลาส Person เป็นคลาสแม่ และ คลาส Student เป็นคลาสลูก ซึ่ง constructor ของ Person มีการแสดงผลว่า "Person class Constructor" ส่วน constructor ของ Student มีการเรียกใช้ super() เพื่อดึงเอา constructor ของ Person มาใช้ และพิมพ์ของตัวเองว่า "Student class Constructor" ใน main เมื่อมีการสร้าง object s จาก คลาส Student มันจึงแสดงผลมาทั้งสองคลาส


C++

C++ มีการเรียกใช้ constructor ของคลาสแม่ คล้าย C# แต่รูปแบบการเขียนไม่เหมือนกัน โดยใน C++ ใช้ชื่อคลาสแม่ในการเรียก constructor ซึ่ง C# ใช้ คำสั่ง base() C++ ถ้าคลาสแม่มี constructor ที่มีการรับพารามิเตอร์ ต้องเรียกจากคลาสลูกด้วยการใช้ initializer list ใน constructor ของคลาสลูก เพื่อส่งค่าไปให้กับ constructor ของคลาสแม่ หากคลาสแม่ไม่มี constructor ที่กำหนดเอง คลาสลูกจะใช้ default constructor ของคลาสแม่โดยอัตโนมัติเช่นเดียวกับภาษา C#

example

C++
#include <iostream>
using namespace std;
class Base {
    int x;
public:
    // Default constructor
    Base() {
        cout << "Base class default constructor\n"; 
    }

    // Parameterized constructor
    Base(int x) { 
        this->x = x;
        cout << "Base class parameterized constructor\n"; 
    }
};

class Derived : public Base {
    int y;
public:
    // Default constructor
    Derived() {
        cout << "Derived class default constructor\n";
    }

    // Parameterized constructor
    Derived(int i) : Base(i) {
        cout << "Derived class parameterized constructor\n";
    }
};

int main() {
    Base b;          // Construct base class object
    Derived d1;     // Construct derived class object with default constructor
    Derived d2(10); // Construct derived class object with parameterized constructor
}

output

Base class default constructor
Base class default constructor
Derived class default constructor
Base class parameterized constructor
Derived class parameterized constructor

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


Python

python เป็นภาษาที่มีความยืดหยุ่นสูง จึงมีการสืบทอดที่ง่ายกว่า C# กล่าวคือ มันสามารถเรียกใช้ constructor ของคลาสแม่โดย ใช้คีย์เวิร์ดว่า super() เช่นเดียวกับ java แต่pythonไม่ต้องระบุ data type แบบภาษา java C# และ C++ และการสืบทอดจะเขียนชื่อคลาสแม่ในวงเล็บของคลาสลูก class คลาสลูก (คลาสแม่): มีเมธอด __init__ สำหรับกำหนดค่าเริ่มต้นของ object หรือก็คือ constructor ของภาษา python ซึ่งแตกต่างจากภาษา java C# และ C++ ที่มีการสร้าง constructor โดยใช้ชื่อคลาสตัวเองเป็นชื่อเมธอด

example

python
class Emp():
    def __init__(self, id, name, Add):
        self.id = id
        self.name = name
        self.Add = Add

# Class freelancer inherits EMP
class Freelance(Emp):
    def __init__(self, id, name, Add, Emails):
        super().__init__(id, name, Add)
        self.Emails = Emails

Emp_1 = Freelance(103, "Suraj kr gupta", "Noida" , "KKK@gmails")
print('The ID is:', Emp_1.id)
print('The Name is:', Emp_1.name)
print('The Address is:', Emp_1.Add)
print('The Emails is:', Emp_1.Emails)

output

The ID is: 103
The Name is: Suraj kr gupta
The Address is: Noida
The Emails is: KKK@gmails

จากตัวอย่างข้างต้น มีคลาส Emp เป็นคลาสแม่ และ คลาส Freelance เป็นคลาสลูก ซึ่ง Emp มีconstructor ที่รับพารามิเตอร์ id , name , Add เพื่อเก็บข้อมูลพนักงาน ในส่วนของ Freelance ซึ่งสืบทอดมาจาก Emp มีการใช้ super().__init__(id, name, Add) เพื่อเรียกใช้ constructor ของคลาสแม่ และเพิ่มคุณสมบัติใหม่ในคลาสตัวเองคือ Emails และมีการสร้าง object Emp_1 จากคลาส Freelance โดยส่งค่าไปยัง constructor ทั้งของแม่และลูก และพิมพ์แสดงผล id ,name ,address และ email ของ object ออกมา


Video Presentation


สไลด์นำเสนอ


Reference

C#

  • ส่วนเนื้อหา Inheritance in Constructors ของ c#:

GeeksforGeeks. (2023, Apr 06). C# | Inheritance in Constructors. GeeksforGeeks. https://www.geeksforgeeks.org/c-sharp-inheritance-in-constructors/

Microsoft. (2022, Feb 17). Inheritance - derive types to create more specialized behavior. Microsoft. https://docs.oracle.com/javase/tutorial/java/IandI/subclasses.html

W3Schools. (n.d.). C# Inheritance. W3Schools. https://www.w3schools.com/cs/cs_inheritance.php

  • ส่วนตัวอย่างโค้ด ของ c#

Mohsen Bazmi. (2024, Mar 28). C# Constructor Inheritance. tutorials.eu. https://tutorials.eu/c-constructor-inheritance/

java

  • ส่วนของเนื้อหา Inheritance in Constructors ของ java:

W3Schools. (n.d.). C# | Java Inheritance. W3Schools.https://www.w3schools.com/java/java_inheritance.asp

Oracle. (n.d.). Inheritance. Oracle. https://docs.oracle.com/javase/tutorial/java/IandI/subclasses.html

  • ส่วนตัวอย่างโค้ด ของ java

GeeksforGeeks. (2023, Dec 15). C# | Super Keyword in Java. GeeksforGeeks.https://www.geeksforgeeks.org/super-keyword/

c++

  • ส่วนของเนื้อหา Inheritance in Constructors ของ C++:

GeeksforGeeks. (2024, Oct 11). Inheritance in C++. GeeksforGeeks. https://www.geeksforgeeks.org/inheritance-in-c/

  • ส่วนตัวอย่างโค้ด ของ C++

Sruthy. (2024, Mar 10). C# | Inheritance In C++. softwaretestinghelp.https://www.softwaretestinghelp.com/inheritance-in-cpp/

python

  • ส่วนของเนื้อหา Inheritance in Constructors ของ python:

W3Schools. (n.d.). C# | Python Inheritance. W3Schools.https://www.w3schools.com/python/python_inheritance.asp

GeeksforGeeks. (2024, Jul 25). Inheritance in C++. GeeksforGeeks. https://www.geeksforgeeks.org/__init__-in-python/

  • ส่วนเนื้อหาและตัวอย่างโค้ด ของ java

GeeksforGeeks. (2024, Jul 7). C# | Python super(). GeeksforGeeks. https://www.geeksforgeeks.org/python-super/

Last updated