Static class

ธนภัทร รุจิชานันทกุล 650710550

Static Class คืออะไร

Static Class คือ คลาสที่ไม่สามารถสร้าง Object ได้ ก็คือไม่สามารถใช้ new operator ได้ และเป็น sealed class ทำให้ไม่สามารถ Inherit ได้ กล่าวคือ ไม่สามารถเป็นคลาสแม่ (base case) ให้กับคลาสใด ๆ และ ได้ โดยภายในคลาสที่เป็น static จะสามารถเก็บได้แค่ Static Member เท่านั้น!!

Static class เสมือนกล่องเครื่องมือ

หน้าที่หลักของ Static class เปรียบเสมือนเป็นกล่องเครื่องมือสารพัดประโยชน์ ที่ได้รวบรวม Method ที่ทำงานกับพารามิเตอร์ที่รับเข้า และไม่จำเป็นต้องเข้าถึงหรือกำหนดค่าให้กับฟิลด์ เช่น Math Library เป็น static class ที่มีการรวม Data และ Method ที่เกี่ยวข้องกับการคำนวณทางคณิตศาสตร์ไว้ โดยเราสามารถเข้าถึง Data และ Method ของ Class Math ได้โดย ไม่ต้องสร้าง object ของคลาส

การสร้าง Static class

สามารถสร้าง Static class ได้ด้วยการระบุ static keyword

Concept: static class ก็เหมือนกับการสร้าง class ที่มีแค่ static member และ private constructor โดย private constructor ช่วยป้องกันไม่ให้มีการสร้าง object

static class ClassName {}

การเข้าถึง Static class

เข้าถึงสมาชิกของคลาสแบบสแตติกโดยใช้ชื่อคลาสโดยตรง

//Math เป็น static class
Math.Abs(-9.89); // 9.89
Math.Pow(4,2) // 16.0
Math.PI // 3.14159265358979323846

Static Member

เป็นสมาชิกที่เป็นของคลาสโดยตรง ไม่ใช่ของ instance ตัวใดตัวนึง โดยมีการระบุ static keyword ไว้ static member ประกอบไปด้วย constructor, method, property, field, constant และ event แต่ constant จะไม่มี static keyword เนื่องจากว่ามีพฤติกรรมเหมือน static และถูกมองว่าเป็นค่าคงที่ในระดับคลาสแล้ว

static method

  • สามารถเข้าถึงได้แค่สมาชิก static member แต่ไม่สามารถเข้าถึง non-static member ได้

  • สามารถทำ overloaded ได้ แต่ไม่สามารถทำ override ได้

static constructor

  • ใช้ในการกำหนดค่าเริ่มต้นให้กับ static data

  • ถูกเรียกใช้อัตโนมัติ เมื่อมีการเข้าถึงสมาชิกของ static class และ ถูกเรียกใช้เพียงครั้งเดียวเท่านั้น

ตัวอย่าง Static member
public static class StaticMemberExample
{
    //static field
    public static int NumberOfWheels;
    
    //Constant
    public const double PI = 3.14159265358979323846;

    //static property
    public static int SizeOfGasTank
    {
        get
        {
            return 15;
        }
    }
    
    //static constructor
    static StaticMemberExample(){
        NumberOfWheels = 4;
    }
    
    //static method
    public static void Drive() { }

    //static event
    public static event EventType? RunOutOfGas;

}

ข้อดีของการใช้ Static class

  • Compiler จะการันตีว่าจะไม่มี object ที่ถูกสร้างจากคลาสนี้ และ ไม่มีสมาชิกของคลาสที่นอกเหนือจาก static member ภายในคลาส

  • ไม่ต้องสร้าง object ของคลาส

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

using System;

namespace ExampleOfStaticClass {

    // Creating static class
    // Using static keyword
    static class Author {

        // Static data members of Author
        public static string A_name;
        public static string L_name;
        public static int T_no;

        // Static constructor of Author
        static Author() 
        {
            // Initializing static members
            A_name = "Ankita";
            L_name = "CSharp";
            T_no = 84;

            Console.WriteLine("Static constructor called.");
        }

        // Static method of Author
        public static void details()
        {
            Console.WriteLine("The details of Author is:");
        }
    }

    // Driver Class
    public class Main {

        // Main Method
        static public void Main()
        {

            // Calling static method of Author
            Author.details();

            // Accessing the static data members of Author
            Console.WriteLine("Author name : {0} ", Author.A_name);
            Console.WriteLine("Language : {0} ", Author.L_name);
            Console.WriteLine("Total number of articles : {0} ", Author.T_no);
        }
    }
 }
Output
Static constructor called.
The details of Author is:
Author name : Ankita 
Language : CSharp 
Total number of articles : 84

อธิบาย Code

มี static class ชื่อ Author ที่มี static field อยู่ในบรรทัดที่ 10-12 , static method อยู่ในบรรทัดที่ 25-30 , static constructor อยู่ในบรรทัดที่ 15-23

มี non-static class ที่มี ฟังก์ชัน main ในคลาส Main มีการเข้าถึงสมาชิกของ static class Author โดยใช้ชื่อ Class ตามด้วย สมาชิก เช่น Author.details()

ในบรรทัดที่ 40 มีการเข้าถึงสมาชิกภายในคลาส static เป็นครั้งแรก โปรแกรมจะไปสั่งให้ static constructor ทำงานโดยอัตโนมัติ แล้วจึงค่อยทำงานในส่วนของ Method details() เป็นลำดับต่อไป โดยที่ static constructor จะถูกเรียกใช้เพียงครั้งเดียวเท่านั้น

ในบรรทัดที่ 41-43 เป็นการเข้าถึง สมาชิกของคลาส static โดยใช้ Author.A_name, Author.L_Name และ Author.T_no

สรุปประเด็นสำคัญของ Static class

  1. Static class ไม่สามารถสร้าง Object ได้โดยใช้คำสั่ง new operator

  2. เก็บได้แค่ที่เป็น Static Member เท่านั้น

  3. เข้าถึง Static class โดยใช้ ชื่อ คลาสโดยตรง

  4. Static class เป็น sealed class คือ ไม่สามารถสืบทอดได้

  5. Static constructor จะถูกเรียกใช้งานโดยอัตโนมัติ เมื่อมีการเข้าถึง Static member ใน Static class และถูกเรียกใช้เพียงครั้งเดียวเท่านั้น

  6. this keyword ไม่สามารถใช้ได้ใน static method เพราะ this ไว้ใช้ระบุ instance ของคลาส

ความแตกต่างระหว่าง Static class และ Non-static class

Static class
Non-static class

ใช้ static keyword ใน การสร้าง class

ไม่ต้องใช้ static keyword ในการสร้าง class

ไม่อนุญาติให้มีการสร้าง Object

อนุญาติให้มีการสร้าง Object โดยใช้ new keyword

สมาชิกภายในคลาส สามารถเข้าถึงได้โดยตรงจากชื่อ class

สมาชิกภายในคลาส ไม่สามารถเข้าถึงได้โดยตรงจากชื่อ class

สมาชิกภายในคลาสเก็บได้แค่ Static member เท่านั้น ทุกสมาชิกต้องระบุ static keyword

สมาชิกภายในคลาสเก็บได้ทั้ง static member และ non-static member ทุกสมาชิกไม่จำเป็นต้องมี static keyword

ไม่สามารถสืบทอดคลาสได้

สามารถสืบทอดคลาสได้

เปรียบเทียบ Static class ในภาษา C# กับภาษา C++ , Java , Python

ภาษา C#

มี static class โดยตรง

ข้อกำหนด

  • ไม่สามารถสร้าง object ของคลาสได้

  • ไม่สามารถสืบทอดได้

  • ทุกสมาชิกเป็น static member

using System;

static class MyStaticClass // คลาสที่เป็น static
{
    private static int myStaticMember; // ตัวแปร static

    // Static Property สำหรับเข้าถึงและตั้งค่าตัวแปร static
    public static int MyStaticMember
    {
        get { return myStaticMember; } // Getter
        set { myStaticMember = value; } // Setter
    }

    // ฟังก์ชัน static สำหรับการคำนวณค่า square
    public static int SquareMyStaticMember()
    {
        return myStaticMember * myStaticMember;
    }
}

public class TestMyStaticClass
{
    public static void Main(string[] args)
    {
        MyStaticClass.MyStaticMember = 5; // ตั้งค่าผ่าน property
        Console.WriteLine("Static value: " + 
            MyStaticClass.MyStaticMember);
        Console.WriteLine("Value squared: " + 
            MyStaticClass.SquareMyStaticMember());

        // ไม่สามารถสร้าง object ของ MyStaticClass ได้
        // MyStaticClass x = new MyStaticClass(); // จะเกิดข้อผิดพลาด
    }
}
Output
Static value: 5
Value squared: 25

ภาษา C++

ไม่มี static class โดยตรง เหมือนอย่างภาษา C#

แต่เราสามารถเลียนแบบให้ใกล้เคียงกับ static class ใน C# ได้ โดยวิธีการต่อไปนี้

  • ใช้ final keyword เพื่อป้องกันการสืบทอด สำหรับ C++ 11 เป็นต้นไป ถึงจะมี final keyword

  • ทำให้คลาสไม่สามารถสร้างอินสแตนซ์ได้โดยใช้ private constructors

  • กำหนดให้เมธอดและตัวแปรเป็น static

#include <iostream>

class MyStaticClass final {  // ใช้ final เพื่อป้องกันการสืบทอด
    private:
        static int myStaticMember; // ตัวแปร static
    
        // Constructor เป็น private เพื่อป้องกันการสร้าง object
        MyStaticClass() {}
    
    public:
        // ฟังก์ชัน static สำหรับตั้งค่าตัวแปร static
        static void setMyStaticMember(int val) {
            myStaticMember = val;
        }
    
        // ฟังก์ชัน static สำหรับดึงค่าตัวแปร static
        static int getMyStaticMember() {
            return myStaticMember;
        }
    
        // ฟังก์ชัน static สำหรับการคำนวณค่า square
        static int squareMyStaticMember() {
            return myStaticMember * myStaticMember;
        }
};

// กำหนดค่าเริ่มต้นให้กับ myStaticMember
int MyStaticClass::myStaticMember = 0; // กำหนดค่าเริ่มต้นที่นี่

int main() {
    // ใช้ :: เข้าถึง static member
    MyStaticClass::setMyStaticMember(5);
    std::cout << "Static value: " << MyStaticClass::getMyStaticMember() 
    << std::endl;
    
    std::cout << "Value squared: " << MyStaticClass::squareMyStaticMember() 
    << std::endl;

    // ไม่สามารถสร้าง object ของ MyStaticClass ได้
    // MyStaticClass x; // จะเกิดข้อผิดพลาด

    return 0;
}
Output
Static value: 5
Value squared: 25

ภาษา Java

ไม่มี static class โดยตรง เหมือนอย่างภาษา C#

ภาษา Java มีการรองรับ static variable, static method, static block, static class

Java มี static nested class แต่ไม่สามารถทำให้คลาสบนสุด เป็น static ได้ แต่เราสามารถเลียนแบบให้ใกล้เคียงกับ static class ใน C# ได้ โดยวิธีการต่อไปนี้

  • ประกาศคลาส ด้วย final keyword เพื่อป้องกันไม่ให้มีการสืบทอดคลาสนี้

  • สร้าง constructor ที่เป็น private ช่วยให้ไม่สามารถสร้าง object ของคลาสได้

  • เก็บสมาชิกที่เป็น static member คือ ประกาศทุกตัวเป็น static

final class MyStaticClass { //final เพื่อป้องกันการสืบทอด

    private static int myStaticMember; // ตัวแปร static
    
    private MyStaticClass () { // private constructor ป้องกันการสร้าง object
        
    }
    
    // ฟังก์ชัน static สำหรับตั้งค่าตัวแปร static
    public static void setMyStaticMember(int val) {
        myStaticMember = val;
    }
    
    // ฟังก์ชัน static สำหรับดึงค่าตัวแปร static
    public static int getMyStaticMember() {
        return myStaticMember;
    }
    
    // ฟังก์ชัน static สำหรับการคำนวณค่า square
    public static int squareMyStaticMember() {
        return myStaticMember * myStaticMember;
    }
}

public class TestMyStaticClass {
     public static void main(String[] args){
        MyStaticClass.setMyStaticMember(5);
        System.out.println("Static value: " + MyStaticClass.getMyStaticMember());
        System.out.println("Value squared: " + MyStaticClass.squareMyStaticMember());
        // MyStaticClass x = new MyStaticClass(); 
        // จะเกิดข้อผิดพลาด ไม่สามารถสร้าง object ได้
     }
}
Output
Static value: 5
Value squared: 25

ภาษา Python

ไม่มี static class โดยตรง เหมือนอย่างภาษา C#

แต่เราสามารถเลียนแบบให้ใกล้เคียงกับ static class ใน C# ได้ โดยวิธีการต่อไปนี้

  • ใช้ method __init_subclass__ ใน parent class เพื่อปรับเปลี่ยนพฤติกรรมของ subclass เมื่อไหร่ก็ตามที่มีการสร้าง object คลาสลูกที่มีการสืบทอด แล้ว method __init_subclass__ จะถูกเรียกใช้ที่คลาสแม่ โดยเราจะให้แจ้ง Error เพื่อป้องกันไม่ให้มีการสืบทอด โดยมี cls คือ พารามิเตอร์ที่อ้างถึงคลาสที่กำลังจะถูกสร้าง (subclass) หมายถึง คลาสลูก (subclass) ใหม่ และมี **kwargs (Keyword arguments) เป็น dictionary เก็บข้อมูลแบบ key-value ไว้เก็บพารามิเตอร์ที่จะนำไปใช้ต่อ จะใส่หรือไม่ใส่ค่ามาก็ได้ หากเมธอดนี้ถูกกำหนดเป็นเมธอดปกติ (instance method) เมธอดนี้จะถูกแปลงเป็น class method โดยอัตโนมัติ

  • ทำให้คลาสไม่สามารถสร้างอินสแตนซ์ได้โดยใช้ raise keyword เพื่อโยนข้อผิดพลาด หากมีการสร้าง object

  • กำหนดให้เมธอดและตัวแปรเป็น static โดย method ต้องระบุ @staticmethod และ variable ต้อง ประกาศไว้นอก method ใดๆ เพื่อให้เป็นตัวแปรระดับคลาส

class MyStaticClass:
    __my_static_member = 0  # ตัวแปร static แบบ private

    def __init__(self):
        raise RuntimeError("Cannot instantiate this class")  # ป้องกันการสร้าง object

    def __init_subclass__(cls, **kwargs): # ป้องกันการสืบทอด
        raise TypeError("MyStaticClass Cannot inherit")

    @staticmethod  # ฟังก์ชัน static สำหรับตั้งค่าตัวแปร static
    def set_my_static_member(val):
        MyStaticClass.__my_static_member = val

    @staticmethod  # ฟังก์ชัน static สำหรับดึงค่าตัวแปร static
    def get_my_static_member():
        return MyStaticClass.__my_static_member

    @staticmethod  # ฟังก์ชัน static สำหรับการคำนวณค่า square
    def square_my_static_member():
        return MyStaticClass.__my_static_member ** 2

# ทดสอบการใช้งาน
MyStaticClass.set_my_static_member(5)
print("Static value:", MyStaticClass.get_my_static_member())
print("Value squared:", MyStaticClass.square_my_static_member())

# ทดสอบการ inheritance (จะเกิดข้อผิดพลาด)
#class SubClass(MyStaticClass):  # จะเกิดข้อผิดพลาด
    #pass
Output
Static value: 5
Value squared: 25

Slide Presentation

Video Presentation

Reference

C#

-> เนื้อหา ของ Static class, Static member และ Syntax

Wagner B. (2024, March 19). Static Classes and Static Class Members (C# Programming Guide). C#. Microsoft Learn. https://learn.microsoft.com/en-us/dotnet/csharp/programming-guide/classes-and-structs/static-classes-and-static-class-members

-> เนื้อหา ของ Static class และ Static member และ ตัวอย่าง

Saini, A. (2023, September 20). C# | Static Class. GeeksforGeeks. https://www.geeksforgeeks.org/c-sharp-static-class/

-> เนื้อหา ของ Static class และ Static member

Fairushyn, R. (2023, July 27). Static classes and static class members in C#. LinkedIn.https://www.linkedin.com/pulse/static-classes-class-members-c-roman-fairushyn/

-> เนื้อหา ของ Static class และ Static member

Kumar, A. (2024, May 27). Static Class in C#. Naukri Code 360. https://www.naukri.com/code360/library/static-class-in-c

Java

-> เนื้อหา ของ Static class ใน java

Tutorialspoint. (n.d.). Java - Static Classes. Tutorialspoint. https://www.tutorialspoint.com/java/java_static_class.htm

-> เนื้อหา ของ Static class ใน java

GeeksforGeeks. (2023, November 9). Static class in Java. GeeksforGeeks. https://www.geeksforgeeks.org/static-class-in-java/

-> เนื้อหา ของ Static class ใน java

Vypirailenko, A. (2023, April 28). What is a static class in Java? CodeGym. https://codegym.cc/groups/posts/what-is-a-static-class-in-java

-> เนื้อหา ของ Static class ใน java

GeeksforGeeks. (2022, May 10). Static blocks in Java. GeeksforGeeks. https://www.geeksforgeeks.org/static-blocks-in-java/

-> วิธีเลียนแบบ Static class ใน C# ของ Java

Bourque, B. (2019, February 18). What is a "static class" in Java? [closed]. Stack Overflow. https://stackoverflow.com/questions/7486012/what-is-a-static-class-in-java

-> ดู class math เป็นเหมือน static class เป็นแนวทาง

Oracle. (n.d.). Class Math (Java SE 11 & JDK 11 ). Oracle.https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/lang/Math.html

-> ดู class math เป็นเหมือน static class เป็นแนวทาง

HtmlDoclet G. (2007, April 21). Source for java.lang.Math. GNU Classpathhttps://developer.classpath.org/doc/java/lang/Math-source.html

C++

-> เนื้อหา Static class ใน c++

Tutorialspoint. (n.d.). How to create a static class in C++?. Tutorialspoint.https://www.tutorialspoint.com/how-to-create-a-static-class-in-cplusplus

-> การใช้ final keyword ใน c++

GeeksforGeeks. (2020, November 3). C++ final specifier. GeeksforGeeks. https://www.geeksforgeeks.org/c-final-specifier/

Python

-> การประกาศ static variable ใน python

Sinha, S. (2022, August 30). What is a Static Variable in Python?. Scaler Topics. https://www.scaler.com/topics/static-variable-in-python/

-> การสร้าง object ใน python

W3Schools. (n.d.). Python Classes and Objects. W3Schools. https://www.w3schools.com/python/python_classes.asp

-> การใช้ raise keyword ใน python

W3Schools. (n.d.). Python Raise an Exception. W3Schools. https://www.w3schools.com/python/gloss_python_raise.asp

-> เนื้อหาของ __init_subclass__ method

Python Documentation. (n.d.). 3. Data model, 3.3.3. Customizing class creation. Python Documentation. https://docs.python.org/3/reference/datamodel.html#object.__init_subclass__

-> เนื้อหา **kwargs

DH Team. (2024, February 1). การใช้งาน *ergs และ **kwargs ในภาษา Python. devhub. https://devhub.in.th/blog/args-kwargs-python

Last updated