หนึ่งในคุณสมบติที่ดีที่สุดของไพธอนก็คือ คลาส (Class) นี่เอง คลาสเป็นความสามารถที่แถมมากับหลักการ Object-Oriented Programming ซึ่งเหมาะกับการพัฒนาโปรแกรมทั้งขนาดเล็ก ขนาดกลาง และขนาดใหญ่ มีจุดเด่นที่น่าสนใจของคลาสก็คือ การแบ่งปัญหาใหญ่ให้เล็กลงเพื่อแก้ไขในขอบเขตที่จำกัด ทั้งยังช่วยให้การทดสอบง่ายขึ้นอีกด้วย
อย่างไรก็ตามคลาสในไพธอนไม่ตรงตามหลักการของ OOP มากนัก ดังนั้นไพธอนอาจเหมาะเป็นภาษาแรก แต่ไม่เหมาะสำหรับการสอน OOP แน่ๆ
กลับมาดูคลาสในไพธอนดีกว่า เริ่มจากคลาสง่ายๆ
class Person: pass
ตัวอย่างข้างบนเป็นคลาสที่พื้นฐานที่สุด ขณะเดียวกันก็สามารถนำไปประยุกต์ใช้งานได้มากมาย ก่อนอื่นต้องสร้างอ๊อบเจ็กขึ้นมาก่อน
p = Person()
แค่นี้ก็เอา p ไปใช้ได้แล้ว ซึ่งตอนนี้มีสภาพเหมือนกล่องเปล่า อยากใส่อะไรก็ได้
p.name = 'Alice' p.age = 8 print p.name,p.age
อย่างไรก็ตามการใช้งานแบบข้างบนจะมีข้อเสียนิดหน่อย ตรงที่อ๊อบเจ็กอื่นของคลาส Person
จะไม่มี name และ age ซึ่งแก้ไขได้โดยการกำหนดค่าเริ่มต้น
class Person: name = 'noname' age = 0
ซึ่งจะรับประกันได้ว่า Person ทุกอ็อบเจ็กจะมี name และ age เสมอ
แต่ยังไม่สามารถกำหนดค่าเริ่มต้นแบบสวยๆ ได้
class Person: def __init__(self,name,age): self.name = name self.age = age
วิธีกำหนดค่าเริ่มต้นจะต้องใช้ constructor เข้ามาช่วย ในไพธอนนั้นจะเป็นเมธอดชื่อ
__init__ นั่นเอง ทุกเมธอดในคลาสของไพธอนจะใช้พารามิเตอร์ตัวแรกแทนตัวเอง
ซึ่งปกติจะใช้ชื่อ self สำหรับคนที่ชินกับภาษาซี หรือจาวา self ก็คือ this นี่เอง
วิธีแบบนี้ทำให้การเขียนโปรแกรมเข้าใจง่ายขึ้นมาก เพราะไม่ต้องงงว่า this คืออะไร
มีที่มาอย่างไร เวลาใช้จึงเปลี่ยนไปเล็กน้อย
p = Person('Alice',8)
ถ้าอยากใส่เมธอดเพิ่มเติมก็ใส่เข้าไปในคลาสได้
class Person: def __init__(self,name,age): self.name = name self.age = age def show(self): print '%s is %d years old.' % (self.name,self.age) p = Person('Alice',8) p.show()
หรือถ้าจะให้ดูเป็นไพธอนมากกว่านี้ก็ต้องแก้ constructor นิดนึง
class Person: def __init__(self,**kw): self.name = kw.get('name','noname') self.age = kw.get('age',0) def show(self): print '%s is %d years old.' % (self.name,self.age) p = Person(name='Alice',age=8) p.show()
หรือจะเป็นแบบข้างล่างก็ได้
class Person: name = 'noname' age = 0 def __init__(self,**kw): self.__dict__.update(kw) def show(self): print '%s is %d years old.' % (self.name,self.age) p = Person(name='Alice',age=8) p.show()
กระทู้เก่าๆ จะย้ายตามไปในภายหลัง ตอนนี้ปิดการโพสต์กระทู้ไว้ เหลือไว้เฉพาะอ้างอิงเท่านั้น
class ใน python ไม่ตรงตามหลัก OOP ตรงไหนอะครับ? เข้าถึง attribute ง่ายเกินไป?
ผมมองว่าไม่ใช่ class นะ แต่เป็น object ต่างหาก เพราะว่าไม่มี information hiding เลย ใครจะล้วงเอาอะไรไป หรือลบ attribute ของ object ก็ได้ เช่น
นอกจากนั้นถ้าเราสร้างคลาสแบบนี้
เวลาสร้าง object นั้น attribute name จะไม่ใช่ของ person จริงจนกว่าจะ assign ค่าให้มัน และพอลบ attribute แล้วก็ยังสามารถอ้างไปถึง attribute ของ class ได้อีก
มันเลยดูงงๆ นิดหน่อย แต่ถ้าเขียน code ดีๆ ตาม convention ก็จะไม่งงนะครับ
แถมคำถามหน่อย...
เวลา define class นี่ควรใช้แบบ Person หรือแบบ Person2 (แบบที่ไม่ใช้
__init__กับแบบที่ใช้__init__ตามลำดับ) ดีครับ?