ผู้กล้า
ขึ้น ซึ่งผู้กล้านี้ก็อาจสามารถแบ่งย่อยเป็นอาชีพต่างๆได้อีกเช่นนักรบหรือจอมเวทผู้กล้า
class อาวุธ:
def __init__(self,ชื่อ,พลังโจมตีกายภาพ,พลังโจมตีเวทย์,ความทนทาน):
self.ชื่อ = ชื่อ
self.พลังโจมตีกายภาพ = พลังโจมตีกายภาพ
self.พลังโจมตีเวทย์ = พลังโจมตีเวทย์
self.ความทนทาน = ความทนทาน
class เสื้อผ้า:
def __init__(self,ชื่อ,พลังป้องกัน,ความทนทาน):
self.ชื่อ = ชื่อ
self.พลังป้องกัน = พลังป้องกัน
self.ความทนทาน = ความทนทาน
class ผู้กล้า:
def __init__(self,ชื่อ,เลเวล=1,ความแข็งแรง=4,ความอดทน=4,hpสูงสุด=10):
self.ชื่อ = ชื่อ
self.เลเวล = เลเวล
self.ความแข็งแรง = ความแข็งแรง
self.ความอดทน = ความอดทน
self.hpสูงสุด = hpสูงสุด
self.hp = hpสูงสุด
เสื้อผ้า = เสื้อผ้า('ชุดเก่าๆ',3,5)
อาวุธ = อาวุธ('มีดสั้นเก่าๆ',3,0,5)
เงินเดือน = 500
def พลังโจมตี(self):
return self.ความแข็งแรง + self.อาวุธ.พลังโจมตีกายภาพ
def พลังป้องกัน(self):
return self.ความอดทน + self.เสื้อผ้า.พลังป้องกัน
def ถูกโจมตี(self,ความเสียหาย):
if(ความเสียหาย>self.พลังป้องกัน()):
self.hp -= ความเสียหาย - self.พลังป้องกัน()
else:
self.hp -= 1
if(self.hp<0):
self.hp = 0
class นักรบ(ผู้กล้า):
เสื้อผ้า = เสื้อผ้า('ชุดนักรบฝึกหัด',5,5)
อาวุธ = อาวุธ('ดาบฝึกหัด',5,0,5)
class จอมเวท(ผู้กล้า):
def __init__(self,ชื่อ,เลเวล=1,ความแข็งแรง=4,พลังเวทย์=4,ความอดทน=4,hpสูงสุด=10,mpสูงสุด=10):
self.ชื่อ = ชื่อ
self.เลเวล = เลเวล
self.พลังเวทย์ = พลังเวทย์
self.ความแข็งแรง = ความแข็งแรง
self.ความอดทน = ความอดทน
self.hpสูงสุด = hpสูงสุด
self.hp = hpสูงสุด
self.mpสูงสุด = mpสูงสุด
self.mp = mpสูงสุด
เสื้อผ้า = เสื้อผ้า('ชุดจอมเวทฝึกหัด',2,5)
อาวุธ = อาวุธ('คฑาฝึกหัด',0,5,5)
def พลังโจมตีเวทย์(self):
return self.พลังเวทย์ + self.อาวุธ.พลังโจมตีเวทย์
อาวุธ
, เสื้อผ้า
และ ผู้กล้า
ซึ่งใกล้เคียงกับบทที่แล้วแต่ต่างไปเล็กน้อยนักรบ
และ จอมเวท
ซึ่งจะเห็นได้ว่ามีวงเล็บ ผู้กล้า
อยู่ข้างหลัง ซึ่งแสดงถึงว่าทั้ง ๒ คลาสนี้รับทอดมาจาก ผู้กล้า
นั่นเองนักรบ
ไม่ได้มีการเพิ่มหรือแก้ไขเมธอด แต่มีแค่การใส่ค่าแอตทริบิวต์ในคลาส นั่นคือ อาวุธ
และ เสื้อผ้า
ใหม่ ซึ่งแอตทริบิวต์นี้จะไปทับของที่มีอยู่แล้วในคลาส ผู้กล้า
จอมเวท
ก็มีการเปลี่ยน อาวุธ
และ เสื้อผ้า
เหมือนกัน และยังมีการนิยามเมธอด __init__
ขึ้นใหม่ ซึ่งเมธอดนี้จะไปทับ __init__
ทำให้ใช้อันใหม่นี้แทน ซึ่งข้อแตกต่างจะเห็นว่ามีการเพิ่ม พลังเวทย์
และ mpสูงสุด
ขึ้นมาพลังโจมตีเวทย์
ซึ่งไม่ได้ถูกนิยามขึ้นในคลาส ผู้กล้า
ตั้งแต่แรก เมธอดนี้จึงถูกสร้างขึ้นใหม่และใช้ได้เฉพาะออบเจ็กต์ของคลาส จอมเวท
เท่านั้นนักรบ
ไม่มีการนิยาม __init__
ขึ้นมาใหม่ ดังนั้นจึงมีเมธอด __init__
ที่เหมือนกับคลาส ผู้กล้า
ทุกประการ__init__
ของ จอมเวท
นั้นต่างจากของ ผู้กล้า
ไม่มาก แค่เพิ่มพารามิเตอร์ขึ้นมาเท่านั้น ในกรณีแบบนี้เราอาจไม่ต้องเขียนใหม่ทั้งหมดแต่ใช้ฟังก์ชัน __init__
ของ ผู้กล้า
ได้class จอมเวท(ผู้กล้า):
def __init__(self,ชื่อ,เลเวล=1,ความแข็งแรง=4,พลังเวทย์=4,ความอดทน=4,hpสูงสุด=10,mpสูงสุด=10):
ผู้กล้า.__init__(self,ชื่อ,เลเวล,ความแข็งแรง,ความอดทน,hpสูงสุด)
self.พลังเวทย์ = พลังเวทย์
self.mpสูงสุด = mpสูงสุด
self.mp = mpสูงสุด
__init__
ของ ผู้กล้า
ภายในเมธอด __init__
ของ จอมเวท
อีกที โดยพารามิเตอร์ก็ต้องใส่ให้สัมพันธ์กันด้วยผู้กล้า
จะถูกป้อนค่าให้กับแอตทริบิวต์ของออบเจ็กต์ด้วย __init__
ด้านในนี้super
class จอมเวท(ผู้กล้า):
def __init__(self,ชื่อ,เลเวล=1,ความแข็งแรง=4,พลังเวทย์=4,ความอดทน=4,hpสูงสุด=10,mpสูงสุด=10):
super(จอมเวท,self).__init__(ชื่อ,เลเวล,ความแข็งแรง,ความอดทน,hpสูงสุด)
self.พลังเวทย์ = พลังเวทย์
self.mpสูงสุด = mpสูงสุด
self.mp = mpสูงสุด
super
ต้องการอาร์กิวเมนต์ ๒ ตัว ตัวแรกคือคลาส ตัวหลังคือออบเจ็กต์ ในที่นี้ออบเจ็กต์ถูกแทนด้วย self
ผลที่ได้คือเป็นการที่ออบเจ็กต์ของคลาสนี้เรียกเมธอดของซูเปอร์คลาสของคลาสจอมเวท
เรียกใช้เมธอดของคลาส ผู้กล้า
ซึ่งเป็นซูเปอร์คลาสsuper
แล้ว ในอาร์กิวเมนต์ของ __init__
ก็ไม่ต้องมี self
แล้วsuper
นี้ถูกใช้ในโครงสร้างคลาสจะสามารถละอาร์กิวเมนต์ได้ ดังนั้นจึงเขียนแค่นี้ได้
class จอมเวท(ผู้กล้า):
def __init__(self,ชื่อ,เลเวล=1,ความแข็งแรง=4,พลังเวทย์=4,ความอดทน=4,hpสูงสุด=10,mpสูงสุด=10):
super().__init__(ชื่อ,เลเวล,ความแข็งแรง,ความอดทน,hpสูงสุด)
self.พลังเวทย์ = พลังเวทย์
self.mpสูงสุด = mpสูงสุด
self.mp = mpสูงสุด
ผู้เล่นA = จอมเวท('มานะ',1,5,8,4,12,11)
ผู้เล่นB = นักรบ('พากเพียร',1,7,6,14)
print(ผู้เล่นA.เสื้อผ้า.ชื่อ) # ได้ ชุดจอมเวทฝึกหัด
print(ผู้เล่นB.เสื้อผ้า.ชื่อ) # ได้ ชุดนักรบฝึกหัด
print(ผู้เล่นA.hp) # ได้ 12
ผู้เล่นA.ถูกโจมตี(10)
print(ผู้เล่นA.hp) # ได้ 8
class นักดาบ(นักรบ):
0
class นักธนู(นักรบ):
อาวุธ = อาวุธ('ธนูฝึกหัด',6,0,5)
class จอมเวทมนตร์ดำ(จอมเวท):
0
class จอมเวทมนตร์ขาว(จอมเวท):
0
นักดาบ
และ นักธนู
จะรับทอดเมธอดและแอตทริบิวต์ของ นักรบ
ซึ่งรับทอดแอตทริบิวต์ของ ผู้กล้า
มาอีกต่อนักดาบ
ถือเป็นซับคลาสของ ผู้กล้า
ไปด้วยนักดาบ
ก็จะเป็นอินสแตนซ์ของคลาส นักรบ
แล้วก็เป็นอินสแตนซ์ของคลาส ผู้กล้า
ไปด้วยobject
อยู่แล้วในตัว เพียงแต่สามารถละได้เท่านั้น โดยทั่วไปจึงไม่ต้องเขียนวงเล็บ แต่ถ้าจะเขียนก็จะเห็น
class ผู้กล้า(object):
class ผู้กล้า:
object
นั่นเพราะในไพธอนนั้นข้อมูลทุกอย่างล้วนเป็นออบเจ็กต์ ดังนั้นไม่ว่าอะไรก็ตามจึงเป็นอินสแตนซ์ของคลาสที่ชื่อ object
นั่นเองobject
⇒ ผู้กล้า
⇒ นักรบ
⇒ นักดาบ
นักรบเวทย์
ขึ้นมาเป็นซับคลาสของ นักรบ
กับ นักเวทย์
class นักรบเวทย์(นักรบ,จอมเวท):
0
เสื้อผ้า
กับ อาวุธ
ต่างก็ถูกนิยามใหม่ในคลาส นักรบ
และ จอมเวท
แต่ นักรบ
ขึ้นก่อน ดังนั้นแอตทริบิวต์นี้จะถูกนิยามตาม นักรบ
จอมเวท
มีนิยามเมธอด __init__
ขึ้นมาใหม่แต่ นักรบ
ไม่มี ดังนั้นเมธอด __init__
ของ นักรบเวทย์
ก็จะรับทอด __init__
ของ จอมเวท
ผู้เล่นD = นักรบเวทย์('หรรษา')
print(นักรบเวทย์.เสื้อผ้า.ชื่อ) # ได้ ชุดนักรบฝึกหัด
print(นักรบเวทย์.อาวุธ.ชื่อ) # ได้ ดาบฝึกหัด
print(ผู้เล่นD.mpสูงสุด) # ได้ 10
__
จะไม่สามารถเข้าถึงได้โดยตรงจากภายนอกคลาสผู้กล้า
ใหม่โดยเปลี่ยนแค่ให้แอตทริบิวต์ เงินเดือน
มี __
นำหน้า
class ผู้กล้า:
def __init__(self,ชื่อ):
self.ชื่อ = ชื่อ
__เงินเดือน = 500
ผู้เล่นJ = ผู้กล้า('เจ')
print(ผู้เล่นJ.__เงินเดือน)
AttributeError: 'ผู้กล้า' object has no attribute '__เงินเดือน'
print(ผู้กล้า.__เงินเดือน)
__เงินเดือน
ขึ้นมา
class ผู้กล้า:
def __init__(self,ชื่อ):
self.ชื่อ = ชื่อ
__เงินเดือน = 500
def แสดงเงินเดือน(self):
return self.__เงินเดือน
ผู้เล่นK = ผู้กล้า('เค')
print(ผู้เล่นK.แสดงเงินเดือน()) # ได้ 500
แสดงเงินเดือน
_ผู้กล้า__เงินเดือน
print(ผู้เล่นK._ผู้กล้า__เงินเดือน) # ได้ 500
class ผู้กล้า:
def __init__(self,ชื่อ):
self.ชื่อ = ชื่อ
__เงินเดือน = 500
def แสดงเงินเดือน(self):
return self.__เงินเดือน
class นักรบ(ผู้กล้า):
__เงินเดือน = 1000
ผู้เล่นL = นักรบ('แอล')
print(ผู้เล่นL.แสดงเงินเดือน()) # ได้ 500
แสดงเงินเดือน
ซึ่งมีไว้ใช้คืนค่า __เงินเดือน
นั้นคืนค่าเงินเดือน 500 ซึ่งเป็นค่าของคลาส ผู้กล้า
ทั้งๆที่โดยปกติแล้วหากรับทอดมาแล้วมีการนิยามแอตทริบิวต์ซ้ำมันก็น่าจะถูกเขียนทับ ดังนั้นจึงควรได้ค่า 1000 ซึ่งเป็นค่าใหม่__
จะไม่ถูกเขียนทับในคลาสที่รับทอดมา เพราะชื่อจริงๆของมันจะต้องมีชื่อคลาสนำหน้า ดังนั้นจึงแบ่งแยกกันชัดเจน
print(ผู้เล่นL._ผู้กล้า__เงินเดือน) # ได้ 500
print(ผู้เล่นL._นักรบ__เงินเดือน) # ได้ 1000
แสดงเงินเดือน
ถูกประกาศในคลาส ผู้กล้า
ดังนั้นจึงใช้ __เงินเดือน
ของคลาส ผู้กล้า
แต่หากนิยามเมธอดใหม่ในคลาส นักรบ
ค่า __เงินเดือน
ในคลาส นักรบ
จะถูกใช้แทน__เงินเดือน
เป็น เงินเดือน
ซึ่งไม่มีขีดล่างสองขีดนำหน้า หรือจะมีขีดเดียว หรือจะเป็นชื่ออื่นก็ได้ จะพบว่าผลลัพธ์ที่ได้นั้นจะต่างกันออกไป โดยจะได้ค่า 1000 แทนที่จะเป็น 500
class ผู้กล้า:
def __init__(self,ชื่อ):
self.ชื่อ = ชื่อ
เงินเดือน = 500
def แสดงเงินเดือน(self):
return self.เงินเดือน
class นักรบ(ผู้กล้า):
เงินเดือน = 1000
ผู้เล่นM = นักรบ('เอ็ม')
print(ผู้เล่นM.แสดงเงินเดือน()) # ได้ 1000
print(ผู้เล่นM.เงินเดือน) # ได้ 1000
class ผู้กล้า:
def __init__(self,ชื่อ):
self.ชื่อ = ชื่อ
def __แสดงเงินเดือน(self):
return 500
class นักรบ(ผู้กล้า):
def __แสดงเงินเดือน(self):
return 1000
ผู้เล่นN = นักรบ('เอ็น')
print(ผู้เล่นN._ผู้กล้า__แสดงเงินเดือน()) # ได้ 500
print(ผู้เล่นN._นักรบ__แสดงเงินเดือน()) # ได้ 1000
__
ต่อให้ขึ้นต้นด้วย __
ก็จะไม่มีคุณสมบัติดังที่ว่านี้ เช่นพวกเมธอดพิเศษอย่าง __init__
จะเข้าถึงได้ด้วยชื่อเมธอดตามปกติติดตามอัปเดตของบล็อกได้ที่แฟนเพจ