🇯🇵 日本語 | 🇺🇸 English | 🇪🇸 Español | 🇵🇹 Português | 🇹🇭 ไทย | 🇨🇳 中文

ความรู้เบื้องต้นเกี่ยวกับคลาสใน Python และการเขียนโปรแกรมเชิงวัตถุ [คำอธิบายสำหรับมือใหม่]

หากต้องการเรียกใช้ Python ผ่าน Command Prompt หรือ PowerShell บนคอมพิวเตอร์ของคุณ คุณจำเป็นต้องดาวน์โหลดและติดตั้ง Python ก่อน
หากคุณยังไม่ได้ติดตั้ง กรุณาดูบทความ การติดตั้ง Python และการตั้งค่าสภาพแวดล้อมการพัฒนา เพื่อทำการติดตั้ง Python

สวัสดีทุกท่านที่เพิ่งก้าวเข้ามาในโลกของการพัฒนาเว็บ! ในครั้งนี้ เราจะมาอธิบายแนวคิดที่สำคัญที่ใช้ในภาษาโปรแกรมส่วนใหญ่ นั่นคือ "การเขียนโปรแกรมเชิงวัตถุ (OOP)" และหัวใจหลักของมันใน Python อย่าง "คลาส" ให้เข้าใจง่ายกว่าที่ไหนๆ ไม่ต้องกลัวศัพท์เทคนิคครับ เมื่ออ่านบทความนี้จบ คุณจะร้อง "อ๋อ เข้าใจแล้ว!" อย่างแน่นอน

เป้าหมายหลักของบทความนี้คือการให้ทุกคนได้สัมผัสกับ "ความสนุกที่ได้เห็นโค้ดทำงาน" ครับ ทิ้งทฤษฎียากๆ ไว้ก่อน แล้วมาลองคัดลอกและวางโค้ดที่ใช้งานได้จริง เพื่อสัมผัสถึงความสะดวกสบายของการเขียนโปรแกรมเชิงวัตถุไปพร้อมกัน!


การเขียนโปรแกรมเชิงวัตถุคืออะไรกันแน่?

เมื่อได้ยินคำว่า "การเขียนโปรแกรมเชิงวัตถุ" อาจจะฟังดูยากใช่ไหมครับ? แต่จริงๆ แล้วมันคือแนวคิดที่อยู่รอบตัวเราในชีวิตประจำวันเลยทีเดียว

ตัวอย่างที่มักถูกหยิบยกมาเปรียบเทียบมากที่สุดคือ "แม่พิมพ์ขนม" กับ "ขนม" ครับ

ในโลกของการเขียนโปรแกรม หากเราสร้าง "พิมพ์เขียว" (คลาส) นี้ขึ้นมาครั้งหนึ่งแล้ว เราก็จะสามารถสร้าง "สิ่งของ" (อ็อบเจกต์) ที่เป็นรูปธรรมจากมันได้อย่างมีประสิทธิภาพและในปริมาณมาก นี่คือแนวคิดพื้นฐานของการเขียนโปรแกรมเชิงวัตถุครับ ถ้าเปรียบกับเว็บไซต์ การจัดการองค์ประกอบต่างๆ เช่น "ผู้ใช้", "บทความบล็อก", หรือ "สินค้า" ให้เป็นอ็อบเจกต์แต่ละชิ้น จะช่วยให้ระบบที่ซับซ้อนดูเป็นระเบียบและจัดการได้ง่ายขึ้น


พื้นฐานคลาสใน Python: มาสร้างพิมพ์เขียวกันเถอะ

เอาล่ะครับ เรามาเริ่มสร้าง "พิมพ์เขียว" หรือคลาสใน Python กันเลยดีกว่า โดยในที่นี้เราจะใช้ธีมเกี่ยวกับสุนัข (Dog) ในการดำเนินเรื่องครับ

1. คลาสที่เรียบง่ายที่สุด

ก่อนอื่น มาลองกำหนดคลาสที่ข้างในยังว่างเปล่ากันก่อน แค่นี้ก็ถือว่าเป็น "พิมพ์เขียว" ที่สมบูรณ์แล้วครับ

# กำหนดคลาส (พิมพ์เขียว) ที่ชื่อว่า Dog
class Dog:
    pass # pass หมายถึง "ไม่ต้องทำอะไร" ใช้เมื่อจำเป็นต้องมีคำสั่งตามไวยากรณ์ แต่ยังไม่มีโค้ดที่จะเขียน

# สร้างอ็อบเจกต์ (instance) สุนัขที่เป็นรูปธรรมจากคลาส Dog
my_dog = Dog()

# ลองแสดงผลดูว่า my_dog คืออะไร
print(my_dog)

ผลการรัน:

<__main__.Dog object at 0x10e28a2d0>

เมื่อดูผลลัพธ์ จะเห็นว่าอ็อบเจกต์ของคลาส `Dog` ได้ถูกสร้างขึ้นมาแล้ว (ส่วนที่เป็น `0x...` จะแตกต่างกันไปในแต่ละสภาพแวดล้อมการรัน)


2. การกำหนดคุณลักษณะเฉพาะด้วยเมธอด `__init__`

ต่อไป เราจะมาทำให้สุนัขของเรามีข้อมูลเฉพาะตัว (เรียกว่า property หรือ attribute) เช่น "ชื่อ" และ "สายพันธุ์" กันครับ เหมือนกับการใส่ไส้ให้กับขนมนั่นเอง สิ่งที่เราจะใช้คือเมธอดพิเศษที่ชื่อว่า `__init__` (เป็นฟังก์ชันที่อยู่ในคลาส) ซึ่งเป็นเมธอดสำหรับตั้งค่าเริ่มต้นที่จะถูกเรียกใช้งานโดยอัตโนมัติทันทีที่อ็อบเจกต์ถูกสร้างขึ้น

class Dog:
    # เมธอดสำหรับตั้งค่าเริ่มต้น ที่จะถูกเรียกอัตโนมัติเมื่อสร้างอ็อบเจกต์
    def __init__(self, name, breed):
        # บันทึกข้อมูลลงในอ็อบเจกต์ในรูปแบบ self.ชื่อตัวแปร
        self.name = name
        self.breed = breed
        print(f"{self.name} ({self.breed}) เกิดแล้ว!")

# สร้างอ็อบเจกต์สุนัขพันธุ์ "ชิบะอินุ" ชื่อ "โปจิ"
dog1 = Dog("โปจิ", "ชิบะอินุ")

# สร้างอ็อบเจกต์สุนัขพันธุ์ "อาคิตะ" ชื่อ "ฮาจิ"
dog2 = Dog("ฮาจิ", "อาคิตะ")

# ลองแสดงชื่อและสายพันธุ์ของแต่ละตัว
print(f"ชื่อสุนัขตัวที่ 1: {dog1.name}")
print(f"สายพันธุ์สุนัขตัวที่ 1: {dog1.breed}")
print(f"ชื่อสุนัขตัวที่ 2: {dog2.name}")
print(f"สายพันธุ์สุนัขตัวที่ 2: {dog2.breed}")

พารามิเตอร์ตัวแรกของ `__init__` คือ `self` ซึ่งเป็นคีย์เวิร์ดพิเศษที่อ้างถึงตัวอ็อบเจกต์ที่กำลังจะถูกสร้างขึ้นมาเอง ให้คิดซะว่ามันเป็นเหมือนคาถาครับ การเขียน `self.name = name` ก็คือการผูกข้อมูลเข้ากับอ็อบเจกต์ในความหมายว่า "ชื่อของอ็อบเจกต์นี้คือ..." นั่นเอง

ผลการรัน:

โปจิ (ชิบะอินุ) เกิดแล้ว!
ฮาจิ (อาคิตะ) เกิดแล้ว!
ชื่อสุนัขตัวที่ 1: โปจิ
สายพันธุ์สุนัขตัวที่ 1: ชิบะอินุ
ชื่อสุนัขตัวที่ 2: ฮาจิ
สายพันธุ์สุนัขตัวที่ 2: อาคิตะ

เพียงแค่เรียกใช้คลาสแบบ `Dog("โปจิ", "ชิบะอินุ")` เมธอด `__init__` ก็จะถูกรัน และสร้างอ็อบเจกต์ที่มีข้อมูลของตัวเองขึ้นมา เราสามารถเข้าถึงข้อมูลของอ็อบเจกต์นั้นๆ ได้โดยใช้ `.` (จุด) เชื่อม เช่น `dog1.name`


3. การกำหนดพฤติกรรมด้วยเมธอด

อ็อบเจกต์ไม่ได้มีแค่ข้อมูล (attribute) เท่านั้น แต่ยังสามารถมี "พฤติกรรม" (method) ได้อีกด้วย สำหรับสุนัขแล้ว เรามาลองเพิ่มพฤติกรรมการ "เห่า" กันดีกว่าครับ

class Dog:
    def __init__(self, name, breed):
        self.name = name
        self.breed = breed

    # เพิ่มพฤติกรรม (เมธอด) การเห่าของสุนัข
    def bark(self):
        return f"{self.name}: โฮ่งๆ!"

# สร้างอ็อบเจกต์
my_dog = Dog("โคโระ", "พันธุ์ผสม")

# เรียกใช้เมธอด bark
greeting = my_dog.bark()
print(greeting)

เพียงแค่กำหนดฟังก์ชันด้วย `def` ภายในคลาสเท่านั้นเองครับ ในตอนนี้ก็อย่าลืมใส่ `self` เป็นพารามิเตอร์ตัวแรกเสมอ เราสามารถเข้าถึงชื่อของอ็อบเจกต์นั้นๆ (`self.name`) ผ่าน `self` ได้ครับ

ผลการรัน:

โคโระ: โฮ่งๆ!

ขั้นสูง: การนำพิมพ์เขียวกลับมาใช้ใหม่ด้วย "การสืบทอด"

ตรงนี้แหละครับคือจุดที่การเขียนโปรแกรมเชิงวัตถุทรงพลังอย่างแท้จริง ด้วยกลไกที่เรียกว่า "การสืบทอด" (Inheritance) เราสามารถสร้างคลาสใหม่โดยการเพิ่มหรือเปลี่ยนแปลงฟังก์ชันจากคลาสที่มีอยู่เดิม (พิมพ์เขียว) ได้อย่างง่ายดาย

ตัวอย่างเช่น เราจะสร้างคลาส "สุนัขนำทาง (GuideDog)" ขึ้นมาใหม่โดยใช้คลาส `Dog` ที่เราสร้างไว้ก่อนหน้านี้เป็นพื้นฐาน สุนัขนำทางก็คือสุนัขประเภทหนึ่ง ดังนั้นจึงมี "ชื่อ" และ "สายพันธุ์" และมีความสามารถพื้นฐานในการ "เห่า" เหมือนกัน แต่สิ่งที่เพิ่มเข้ามาคืองานพิเศษ (เมธอด) ในการ "ช่วยเหลือผู้คน"

# คลาสแม่ (superclass) ที่เป็นต้นแบบ
class Dog:
    def __init__(self, name, breed):
        self.name = name
        self.breed = breed
        print(f"สุนัขชื่อ {self.name} เกิดแล้ว เป็นพันธุ์ {self.breed}")

    def bark(self):
        return f"{self.name}: โฮ่ง!"

# สร้างคลาสลูก (subclass) ใหม่โดยสืบทอดจากคลาส Dog
class GuideDog(Dog): # ใส่ชื่อคลาสแม่ไว้ในวงเล็บ
    def assist(self):
        return f"{self.name} กำลังนำทางผู้คนอย่างปลอดภัย"

# สร้างอ็อบเจกต์สุนัขนำทาง
g_dog = GuideDog("แอล", "ลาบราดอร์ รีทรีฟเวอร์")

# สามารถใช้เมธอดของคลาสแม่ (Dog) ได้ด้วย
print(g_dog.bark())

# เมธอดเฉพาะที่เพิ่มเข้ามาในคลาสลูก (GuideDog)
print(g_dog.assist())

เพียงแค่ใส่ชื่อคลาสที่ต้องการใช้เป็นต้นแบบไว้ในวงเล็บหลังชื่อคลาสใหม่ เช่น `class GuideDog(Dog):` การสืบทอดก็เสร็จสมบูรณ์แล้วครับ แค่นี้ `GuideDog` ก็จะได้รับคุณสมบัติ (attribute) ทั้งหมดของ `Dog` (เช่น `name`, `breed`) และเมธอด (`bark`) มาใช้งาน ทำให้สามารถนำโค้ดกลับมาใช้ใหม่ได้มากขึ้นและมีประสิทธิภาพสูงมากครับ

ผลการรัน:

สุนัขชื่อ แอล เกิดแล้ว เป็นพันธุ์ ลาบราดอร์ รีทรีฟเวอร์
แอล: โฮ่ง!
แอล กำลังนำทางผู้คนอย่างปลอดภัย

ตัวอย่างการใช้งานจริง: คลาสสำหรับจัดการบทความบล็อก

ทีนี้ มาดูตัวอย่างที่ใกล้เคียงกับงานสร้างเว็บจริงๆ กันบ้างครับ เราจะสร้างคลาส `BlogPost` สำหรับจัดการบทความในเว็บไซต์บล็อก โดยบทความจะมี "หัวข้อ", "เนื้อหา", "ผู้เขียน" และมีความสามารถในการ "แสดงผล"

import textwrap

class BlogPost:
    def __init__(self, title, content, author):
        self.title = title
        self.content = content
        self.author = author

    # เมธอดสำหรับแสดงข้อมูลบทความอย่างสวยงาม
    def display(self):
        print("--------------------")
        print(f"หัวข้อ: {self.title}")
        print(f"ผู้เขียน: {self.author}")
        print("--- เนื้อหา ---")
        # แสดงผลข้อความยาวๆ โดยมีการตัดบรรทัด
        print(textwrap.fill(self.content, width=40))
        print("--------------------")

# สร้างอ็อบเจกต์บทความหลายๆ ชิ้น
post1 = BlogPost(
    "ความรู้เบื้องต้นเกี่ยวกับคลาสใน Python",
    "การเขียนโปรแกรมเชิงวัตถุคือแนวคิดในการสร้างโปรแกรมเหมือนการประกอบชิ้นส่วน คลาสคือพิมพ์เขียว และอ็อบเจกต์คือตัวตนที่จับต้องได้",
    "Taro Yamada"
)

post2 = BlogPost(
    "พื้นฐานการออกแบบเว็บ",
    "การออกแบบที่ดีไม่ได้คำนึงถึงแค่ความสวยงาม แต่ให้ความสำคัญกับความง่ายในการใช้งานของผู้ใช้เป็นอันดับแรก พื้นที่ว่างและการใช้สีจึงเป็นสิ่งสำคัญ",
    "Hanako Sato"
)

# แสดงผลบทความ
post1.display()
post2.display()

จะเห็นว่าการจัดการบทความแต่ละชิ้นให้เป็นอ็อบเจกต์ ทำให้ข้อมูล (เช่น หัวข้อ) และพฤติกรรม (ฟังก์ชันการแสดงผล) ถูกรวบไว้ด้วยกัน ทำให้การจัดการง่ายขึ้นมากครับ

ผลการรัน:

--------------------
หัวข้อ: ความรู้เบื้องต้นเกี่ยวกับคลาสใน Python
ผู้เขียน: Taro Yamada
--- เนื้อหา ---
การเขียนโปรแกรมเชิงวัตถุคือแนวคิดในการสร้าง
โปรแกรมเหมือนการประกอบชิ้นส่วน คลาสคือ
พิมพ์เขียว และอ็อบเจกต์คือตัวตนที่จับต้องได้
--------------------
--------------------
หัวข้อ: พื้นฐานการออกแบบเว็บ
ผู้เขียน: Hanako Sato
--- เนื้อหา ---
การออกแบบที่ดีไม่ได้คำนึงถึงแค่ความสวยงาม
แต่ให้ความสำคัญกับความง่ายในการใช้งานของผู้ใช้
เป็นอันดับแรก พื้นที่ว่างและการใช้สีจึงเป็น
สิ่งสำคัญ
--------------------

[มาลองรันโค้ดจริงกัน!] ตัวอย่างโค้ด Python ฉบับสมบูรณ์

รอมานานแล้วใช่ไหมครับ! ในส่วนนี้ เราจะนำเสนอโค้ดฉบับสมบูรณ์ของ "โปรแกรมจัดการผู้ใช้" ซึ่งรวบรวมเนื้อหาทั้งหมดที่ผ่านมา คุณสามารถคัดลอกโค้ดนี้ไปบันทึกเป็นไฟล์ `.py` แล้วรันผ่าน Terminal (หรือ Command Prompt) บนเครื่องคอมพิวเตอร์ของคุณได้เลย มาลองสัมผัสประสบการณ์ "โค้ดที่รันได้จริง" กันครับ!

วิธีการรัน

  1. คัดลอกโค้ดทั้งหมดด้านล่าง
  2. นำไปวางในโปรแกรม Text Editor (เช่น VSCode) แล้วบันทึกเป็นชื่อ `user_manager.py`
  3. เปิด Terminal แล้วไปยังไดเรกทอรีที่คุณบันทึกไฟล์ไว้
  4. พิมพ์ `python user_manager.py` แล้วกด Enter

หากเครื่องคอมพิวเตอร์ของคุณยังไม่ได้ติดตั้ง Python สามารถดาวน์โหลดได้ที่ python.org ครับ

# user_manager.py

class User:
    """
    คลาสสำหรับแสดงข้อมูลผู้ใช้ของเว็บไซต์
    """
    def __init__(self, user_id, name, email):
        self.user_id = user_id
        self.name = name
        self.email = email
        self.is_active = True # โดยปกติจะเป็นผู้ใช้ที่ใช้งานอยู่

    def get_profile(self):
        """
        จัดรูปแบบและส่งคืนข้อมูลโปรไฟล์ของผู้ใช้
        """
        status = "ใช้งานอยู่" if self.is_active else "ไม่ใช้งาน"
        return f"ID: {self.user_id}\nชื่อ: {self.name}\nอีเมล: {self.email}\nสถานะ: {status}"

    def deactivate(self):
        """
        ปิดการใช้งานผู้ใช้
        """
        self.is_active = False
        print(f"ผู้ใช้ '{self.name}' ถูกปิดการใช้งานแล้ว")


# ส่วนที่ใช้รันโปรแกรมหลัก
if __name__ == "__main__":
    # สร้างอ็อบเจกต์ผู้ใช้หลายๆ คน
    user1 = User("web-creator", "Taro Tanaka", "tanaka@example.com")
    user2 = User("designer-sato", "Hanako Sato", "sato@example.com")

    # แสดงโปรไฟล์
    print("--- รายชื่อผู้ใช้ ---")
    print(user1.get_profile())
    print("-" * 20)
    print(user2.get_profile())
    print("\n" + "=" * 20 + "\n")

    # ลองปิดการใช้งานผู้ใช้หนึ่งคน
    user2.deactivate()

    print("\n--- รายชื่อผู้ใช้หลังการเปลี่ยนแปลง ---")
    print(user1.get_profile())
    print("-" * 20)
    print(user2.get_profile())

เมื่อรันโค้ดนี้ ใน Terminal ของคุณควรจะแสดงผลลัพธ์ดังนี้ครับ

ตัวอย่างผลการรัน:

--- รายชื่อผู้ใช้ ---
ID: web-creator
ชื่อ: Taro Tanaka
อีเมล: tanaka@example.com
สถานะ: ใช้งานอยู่
--------------------
ID: designer-sato
ชื่อ: Hanako Sato
อีเมล: sato@example.com
สถานะ: ใช้งานอยู่

====================

ผู้ใช้ 'Hanako Sato' ถูกปิดการใช้งานแล้ว

--- รายชื่อผู้ใช้หลังการเปลี่ยนแปลง ---
ID: web-creator
ชื่อ: Taro Tanaka
อีเมล: tanaka@example.com
สถานะ: ใช้งานอยู่
--------------------
ID: designer-sato
ชื่อ: Hanako Sato
อีเมล: sato@example.com
สถานะ: ไม่ใช้งาน

เป็นอย่างไรบ้างครับ? จะเห็นว่าการใช้คลาสทำให้ข้อมูลผู้ใช้และการดำเนินการที่เกี่ยวข้อง (เช่น การปิดใช้งาน) ถูกจัดเก็บรวมกันอย่างเป็นระเบียบ ทำให้โค้ดอ่านง่ายขึ้นอย่างเห็นได้ชัดเลยใช่ไหมครับ


ข้อควรระวังและข้อผิดพลาดที่พบบ่อย

สุดท้ายนี้ ขอแนะนำจุดที่มือใหม่มักจะสะดุดเมื่อเริ่มใช้งานคลาสครับ


ไปยังขั้นตอนถัดไป

เมื่อเข้าใจพื้นฐานของคลาสและการเขียนโปรแกรมเชิงวัตถุแล้ว ต่อไปเรามาลองใช้ไลบรารีมาตรฐานที่มีประโยชน์ของ Python กันครับ การจัดการวันและเวลาเป็นสิ่งที่ต้องทำบ่อยมากในการเขียนโปรแกรม

ในบทความถัดไป เราจะเรียนรู้วิธีการดึงวันที่ปัจจุบันและคำนวณวันที่โดยใช้โมดูล `datetime`

→ วิธีจัดการวันและเวลาด้วยโมดูล datetime