Computer >> คอมพิวเตอร์ >  >> การเขียนโปรแกรม >> Python

Python Inheritance:คำแนะนำทีละขั้นตอน

การสืบทอด Python คือเมื่อคลาสย่อยใช้รหัสจากคลาสอื่น การสืบทอดเป็นคุณสมบัติที่สำคัญในภาษาเชิงวัตถุ เช่น Python ที่ทำให้การเขียนโค้ดง่ายขึ้นและมีประสิทธิภาพมากขึ้น


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

ตัวอย่างเช่น คุณอาจมีคลาสที่เก็บ "บัญชีธนาคาร" และต้องการสร้างคลาสย่อยที่เก็บ "บัญชีธนาคารทอง" ที่สามารถอ้างอิงแอตทริบิวต์ใน "บัญชีธนาคาร" คลาสที่มีอยู่ได้

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

มรดกหลาม

การสืบทอดเป็นคำที่ใช้อธิบายคลาส Python ภายในคลาสอื่น คลาสที่เรียกว่า subclasses หรือ child classes สามารถรับค่าจาก parent classes คล้ายกับการที่ลูกๆ สืบทอดลักษณะนิสัยจากพ่อแม่ในโลกแห่งความเป็นจริง

การสืบทอดมีประโยชน์เพราะช่วยให้เราสร้าง subclasses ที่มีค่าประเภทเดียวกับคลาสพาเรนต์โดยไม่ต้องประกาศประเภทเหล่านั้นหลายครั้ง

ชั้นเรียนสำหรับผู้ปกครอง

คลาสผู้ปกครอง (เรียกอีกอย่างว่า base classes สร้างโครงสร้างหลักที่คลาสย่อยสามารถเข้าถึงได้ เราสามารถสร้างคลาสย่อยได้หลายคลาสโดยไม่ต้องประกาศชุดค่าทั่วไปชุดเดียวกันซ้ำแล้วซ้ำอีก ซึ่งเป็นวิธีการรับคลาสที่ได้รับจากคลาสพาเรนต์

ลองใช้ตัวอย่างเพื่อแสดงให้เห็นว่าสิ่งนี้จะทำงานอย่างไร สมมติว่าเรามีโปรแกรมที่ทำงานร่วมกับบัญชีธนาคารสองประเภทที่แตกต่างกัน:บัญชีหลักและบัญชีย่อย

81% ของผู้เข้าร่วมกล่าวว่าพวกเขารู้สึกมั่นใจมากขึ้นเกี่ยวกับโอกาสในการทำงานด้านเทคโนโลยีหลังจากเข้าร่วม bootcamp จับคู่กับ Bootcamp วันนี้

ผู้สำเร็จการศึกษาจากหลักสูตร bootcamp โดยเฉลี่ยใช้เวลาน้อยกว่าหกเดือนในการเปลี่ยนอาชีพ ตั้งแต่เริ่มต้น bootcamp ไปจนถึงหางานแรก

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

ดังนั้น หากเราต้องการสร้างโปรแกรมด้วยค่าเหล่านี้ ขั้นแรกเราจะกำหนดคลาสสำหรับบัญชีธนาคารของเรา (คลาสหลัก) จากนั้นจึงสร้างคลาสย่อยสำหรับบัญชีธนาคารสองประเภท—ระดับบนสุดและระดับย่อย—ที่เราต้องการสนับสนุน

ต่อไปนี้คือตัวอย่างการประกาศคลาสหลักสำหรับบัญชีธนาคาร:

class BankAccount:
	def __init__(self, forename, surname, balance):
		self.forename = forename
		self.surname = surname
		self.balance = balance

เราได้สร้างคลาส BankAccount ซึ่งเก็บค่าสามค่า:ชื่อ นามสกุล และยอดคงเหลือ นอกจากนี้เรายังสามารถเพิ่มเมธอดในคลาสของเราได้ เช่น

class BankAccount:
	def __init__(self, forename, surname, balance):
		self.forename = forename
		self.surname = surname
		self.balance = balance

	def getDetails(self):
		print("Forename: ", self.forename)
		print("Surname: ", self.surname)

	def getBalance(self):
		print("Balance: $ ", self.balance)

คลาสของเราตอนนี้เก็บค่าสามค่า รวมถึงวิธีการใหม่สองวิธี:รายละเอียดและความสมดุล details สามารถใช้เพื่อค้นหาชื่อและนามสกุลของเจ้าของบัญชีของเราและ balance วิธีการจะคืนยอดคงเหลือของเจ้าของบัญชี

ทุกวิธีและตัวแปรที่เราประกาศใน BankAccount ชั้นเรียนจะสามารถเข้าถึงได้ในชั้นเรียนย่อยของเรา

มาสร้างตัวอย่างบัญชีธนาคารเพื่อแสดงให้เห็นการใช้งานจริงในชั้นเรียนของเรา เราสามารถทำได้โดยใช้รหัสต่อไปนี้:

account = BankAccount("John", "Appleseed", 100)

นี้จะสร้างบัญชีสำหรับ John Appleseed ซึ่งมี 100 เหรียญ เมื่อเรามีบัญชีพร้อมแล้ว ก็เริ่มใช้อ้างอิงได้เหมือนกับที่ทำกับชั้นเรียนอื่นๆ นี่คือตัวอย่างของเราที่ใช้ getBalance() วิธีในบัญชีธนาคารของเราเพื่อดูว่าเรามีเงินเท่าไหร่:

print(account.getBalance())

โปรแกรมของเราส่งคืนข้อมูลต่อไปนี้:

Balance: $ 100

คลาสเด็ก

ในตัวอย่างข้างต้น เราได้ประกาศคลาสหลักที่เก็บบัญชีธนาคาร แต่ถ้าเราต้องการเก็บข้อมูลเกี่ยวกับบัญชีประเภทใดประเภทหนึ่ง เช่น บัญชีของเด็กอายุต่ำกว่า 18 ปี นั่นคือที่ที่ชั้นเรียนสำหรับเด็กเข้ามา

คลาสย่อยหรือคลาสย่อย สืบทอดค่าจากคลาสพาเรนต์ ซึ่งหมายความว่าแต่ละคลาสย่อยจะสามารถอ้างอิงวิธีการและตัวแปรที่เราประกาศในคลาสหลักของเราได้

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

ในการสร้างคลาสย่อย เราสามารถใช้รหัสต่อไปนี้:

class ChildBankAccount(BankAccount):

ChildBankAccount คลาสเป็นลูกของ BankAccount คลาสเพราะ BankAccount อยู่ในวงเล็บ หากเราต้องการให้คลาสย่อยของเรามีค่าเหมือนกับคลาสหลักของเรา—BankAccount —เราสามารถใช้ pass คีย์เวิร์ดแบบนี้:

class ChildBankAccount(BankAccount):
	pass

แต่ดังที่เราได้กล่าวไว้ก่อนหน้านี้ บัญชีย่อยของเราจะต้องเก็บค่าพิเศษ:ตัวแปรที่ระบุว่าบัญชีของผู้ใช้ถูกจำกัด

เพื่อให้บรรลุเป้าหมายนี้ เราจะเพิ่มค่าใหม่ที่เรียกว่า restricted สู่ชั้นเรียนลูกของเรา เราสามารถทำได้โดยใช้รหัสต่อไปนี้:

class ChildBankAccount(BankAccount):
	def __init__(self, forename, surname, balance, restricted=True):
self.forename = forename
self.surname = surname
self.balance = balance
self.restricted = restricted

	def isRestricted(self):
		print("This account is restricted as the user is under 18.")

ตอนนี้ มาทำลายโค้ดของเรากัน

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

สามตัวแรก—ชื่อ นามสกุล และยอดคงเหลือ—เหมือนกับค่าคลาสหลักของเราแต่ restricted เป็นของใหม่และเป็นเอกสิทธิ์สำหรับชั้นเรียนย่อยของเรา โดยค่าเริ่มต้น restricted ถูกตั้งค่าเป็น True .

ดังนั้นหากเราสร้างมาตรฐาน BankAccount (ไม่ใช่ ChildBankAccount ) เราจะไม่สามารถเข้าถึง restricted ค่า. ในทำนองเดียวกัน เราจะไม่สามารถเข้าถึง isRestricted เว้นแต่เราจะสร้าง ChildBankAccount .

นี่คือตัวอย่างของเราในการสร้าง ChildBankAccount และใช้ getBalance() และ isResticted() วิธีการเรียนรู้เพิ่มเติมเกี่ยวกับชั้นเรียนของเรา:

child_account = ChildBankAccount("Bill", "Appleseed", 100) 
print(child_account.getBalance())
print(child_account.isRestricted())

รหัสของเราส่งคืนดังต่อไปนี้:

Balance: $ 100
This account is restricted as the user is under 18.

อย่างที่คุณเห็น โปรแกรมของเรากำหนด ChildBankAccount ใหม่เป็นอันดับแรก สำหรับ Bill Appleseed ซึ่งบัญชีถือ $100 จากนั้นโปรแกรมของเราจะรัน getBalance() วิธีการในชั้นเรียนของเราซึ่งส่งคืนยอดเงินคงเหลือของผู้ใช้ getBalance() ถูกประกาศในคลาสหลัก BankAccount แต่สามารถเข้าถึง ChildBankAccount ผ่าน มรดก .

โปรแกรมของเรายังรัน isRestricted() เมธอด ซึ่งระบุว่าบัญชีของเด็กถูกจำกัดเนื่องจากพวกเขาอายุต่ำกว่า 18 ปี คลาสนี้ประกาศใน ChildBankAccount ซึ่งหมายความว่าไม่สามารถเข้าถึง BankAccount คลาสผู้ปกครองของเราได้ . หากเราต้องการสร้างBankAccountที่ถูกจำกัด เราจะต้องเปลี่ยนคลาสหลัก

นิยามเมธอดของผู้ปกครองใหม่

ในตัวอย่างข้างต้น เราได้ประกาศคลาสหลักชื่อ BankAccount ซึ่งเก็บข้อมูลสำหรับบัญชีธนาคาร นอกจากนี้เรายังได้สร้างคลาสย่อยชื่อ ChildBankAccount ซึ่งเก็บข้อมูลสำหรับผู้ถือบัญชีที่มีอายุต่ำกว่า 18 ปี คลาสนี้สืบทอดวิธีการจาก BankAccount และสร้าง isRestricted() วิธีการ

แต่ถ้าเราต้องการแก้ไขวิธีการคลาสพาเรนต์ที่มีอยู่ล่ะ สมมติว่าเราต้องการ BankAccount ยอดคงเหลือเพื่อส่งคืนข้อความพร้อมยอดคงเหลือและข้อความระบุว่า You are eligible for an overdraft แต่เราไม่ต้องการให้สิ่งนี้ปรากฏสำหรับ ChildBankAccount ผู้ถือ

ในการทำเช่นนี้ เราต้องแทนที่วิธีการหลักของเรา

นี่คือรหัสสำหรับวิธีการหลักที่แก้ไขของเรา BankAccount ซึ่งตอนนี้พิมพ์ข้อความไปยังเจ้าของบัญชีเพื่อแจ้งว่าพวกเขามีสิทธิ์ได้รับเงินเบิกเกินบัญชีเมื่อตรวจสอบยอดคงเหลือ:

class BankAccount:
	def __init__(self, forename, surname, balance):
		self.forename = forename
		self.surname = surname
		self.balance = balance

	def getDetails(self):
		print("Forename: ", self.forename)
		print("Surname: ", self.surname)

	def getBalance(self):
		print("Balance: $ ", self.balance)
		print("You are eligible for an overdraft.")

ทีนี้ ถ้าเราสร้าง BankAccount . ใหม่ สำหรับ John Appleseed และพิมพ์ยอดดุลออกมา เราจะเห็นข้อความว่า You are eligible for an overdraft . นี่คือตัวอย่างของเราในการประกาศบัญชีใหม่และการตรวจสอบยอดคงเหลือ:

account = BankAccount("John", "Appleseed", 100)
print(account.getBalance())

รหัสของเราส่งคืนดังต่อไปนี้:

Balance: $ 100
You are eligible for an overdraft.

แต่การเปลี่ยนแปลงนี้ยังหมายความว่า ChildBankAccount . ของเรา ซึ่งรับค่ามาจาก BankAccount , จะเห็นข้อความด้วย นี่คือตัวอย่างของเราในการสร้าง ChildBankAccount และตรวจสอบยอดเงินตอนนี้ว่าBankAccount .ของเรา คลาสหลักมีการเปลี่ยนแปลง:

child_account = ChildBankAccount("Bill", "Appleseed", 100) 
print(child_account.getBalance())

รหัสของเราส่งคืน:

Balance: $ 100
You are eligible for an overdraft.

เนื่องจากโดยทั่วไปเด็กไม่ได้รับอนุญาตให้เบิกเงินเกินบัญชี เราจะต้องทำการเปลี่ยนแปลงรหัสของเรา ในการดำเนินการดังกล่าว เราต้องแก้ไข ChildBankAccount class และประกาศ getBalance() . ใหม่ ฟังก์ชัน

นี่คือรหัสสำหรับ ChildBankAccount . ของเรา จากข้างบน:

class ChildBankAccount(BankAccount):
	def __init__(self, forename, surname, balance, restricted=True):
self.forename = forename
self.surname = surname
self.balance = balance
self.restricted = restricted

	def isRestricted(self):
		print("This account is restricted as the user is under 18.")

เราจำเป็นต้องเปลี่ยนรหัสนี้เพื่อเพิ่มฟังก์ชันใหม่:getBalance() . ฟังก์ชันนี้จะทำงานในลักษณะเดียวกับที่เราประกาศในคลาสหลัก แต่จะไม่รวมข้อความเกี่ยวกับเงินเบิกเกินบัญชี นี่คือรหัสที่เราจะเพิ่มเพื่อประกาศฟังก์ชันใหม่ของเรา:

…

def getBalance(self):
 print("Balance: $ ", self.balance)

มาลองเอายอดเงินคงเหลือของบุตรหลานของเราตอนนี้:

child_account = ChildBankAccount("Bill", "Appleseed", 100) 
print(child_account.getBalance())

รหัสของเราส่งคืนดังต่อไปนี้:

Balance: $ 100

ในตัวอย่างข้างต้น เราได้เขียนทับ getBalance() วิธีการใน ChildBankAccount ชั้นเรียนเด็ก getBalance()ใหม่ของเรา วิธีการสำหรับ ChildBankAccount แสดงเฉพาะยอดเงินคงเหลือของผู้ใช้ แต่ใน BankAccount . ของเรา คลาส getBalance() วิธีแสดงทั้งยอดเงินของผู้ใช้และข้อความ You are eligible for an overdraft .

การแทนที่เมธอดพาเรนต์อาจมีประโยชน์เมื่อคุณมีเมธอดลูกหลายเมธอด ซึ่งอาจใช้เมธอดที่คล้ายคลึงกันกับพาเรนต์ แต่จำเป็นต้องทำการเปลี่ยนแปลงเฉพาะของเมธอด เช่นเดียวกับกรณีข้างต้น เราต้องการให้บัญชีธนาคารหลักของเราเห็นข้อความเบิกเงินเกินบัญชี แต่ไม่ใช่บัญชีธนาคารลูกของเรา ดังนั้นเราจึงลบล้างวิธีหลักใน ChildBankAccount .

บทสรุป

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

ในบทช่วยสอนนี้ เราได้สำรวจบทบาทของการสืบทอดใน Python เรายังคุยกันถึงวิธีการทำงานของคลาสการสืบทอดและคลาสพาเรนต์และย่อย จากนั้นเราสำรวจวิธีการแทนที่เมธอดพาเรนต์ ตอนนี้คุณพร้อมที่จะทำงานกับคลาสและการสืบทอดเหมือนผู้เชี่ยวชาญ Python แล้ว!