การสืบทอด 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 แล้ว!