Python基礎教學之四:面向對象編程——邁向更高級編程
一、面向對象編程概念
1. 類和對象
- 定義:在面向對象編程(OOP)中,類是創建對象的模板,它定義了對象的屬性和方法。對象是類的實例,具體存在的實體,擁有狀態和行為。
- 關系:類與對象的關系類似于藍圖與房屋的關系。類描述了對象應具有的屬性和能夠執行的方法,而對象則是這些屬性和方法的具體實現。
- 作用域:類中定義的屬性和方法統稱為類的成員。這些成員有不同的訪問級別,如公開、私有等,決定了它們是否可以被類外部的代碼直接訪問。
- 方法:類中的方法代表對象的可執行行為。特殊方法(如
__init__
)有特定的功能,普通方法則執行對象的行為。 - 屬性:屬性是對象的狀態,可以是變量或可調用的對象。在類中,可以定義實例屬性和類屬性,分別屬于對象和類本身。
- self:在類的方法中,第一個參數通常是
self
,指代調用該方法的對象本身。通過self
可以訪問對象的屬性和其他方法。
2. 繼承
- 概念:繼承是OOP的一個核心機制,允許新的類從現有的類繼承屬性和方法,促進代碼重用和邏輯清晰。
- 父類與子類:在繼承關系中,被繼承的類稱為父類(基類),繼承其他類的類稱為子類(派生類)。子類繼承了父類的特征并可以擴展或覆蓋它們。
- 重寫與擴展:子類可以重寫繼承的方法,以修改或擴展其功能。也可以通過
super()
函數調用父類的方法,在此基礎上添加額外的邏輯。 - 多層繼承:Python支持多層繼承,即一個類可以繼承多個父類。這增加了靈活性,但也增加了復雜性。
- 接口繼承與實現繼承:在接口繼承中,子類只繼承方法的簽名而不包括實現,實現繼承則是子類繼承方法的具體實現。
- 菱形繼承問題:當子類從多個父類繼承時,可能出現祖父類的方法被調用多次的問題,這需要通過合適的繼承結構來解決。
- 抽象類與接口:抽象類和接口是特殊的類,它們定義了一組方法,但本身不提供實現。子類必須實現這些方法才能成為具體的類。
3. 封裝
- 原理:封裝是將數據和操作數據的方法組織在一起的過程,隱藏內部實現細節,只暴露必要的接口給外部。
- 作用:封裝減少了類和模塊之間的依賴,提高了代碼的可讀性和易維護性。
- 訪問控制:Python沒有嚴格的訪問控制機制,但通過命名約定(如使用下劃線前綴)來標識私有成員,限制直接訪問。
- getter和setter:使用getter和setter方法來讀取和修改屬性值,可以在方法中加入邏輯驗證,保證數據的有效性和完整性。Getter and Setter in Python - GeeksforGeeks
- 描述符:描述符是一種特殊的對象,可以實現屬性的getter和setter功能,用于高級屬性訪問控制。
- 屬性注解:Python允許使用注解來標記屬性的類型,雖然這不直接影響封裝,但有助于代碼的文檔化和類型檢查。
- 模塊化:封裝促進了代碼模塊化,使得各個模塊和類的職責單一,專注于完成特定任務,減少耦合。
二、類的創建和使用
1. 定義類
- 使用
class
關鍵字定義類,后跟類名和冒號。 - 類定義中包括屬性和方法。
-
class ClassName:<statement-1>...<statement-N>
2. 實例化對象
- 使用類名后跟括號來創建類的實例(對象)。
- 對象可訪問類中定義的屬性和方法。
-
#!/usr/bin/python3class Complex:def __init__(self, realpart, imagpart):self.r = realpartself.i = imagpart x = Complex(3.0, -4.5) print(x.r, x.i) # 輸出結果:3.0 -4.5
3. 構造方法__init__
__init__
方法用于初始化新創建的對象。- 當創建對象時自動調用,可設置初始屬性值。
三、繼承和多態
1. 繼承的實現
- 通過在類定義時指定父類來實現繼承。
- 子類可以繼承父類的屬性和方法。
class DerivedClassName(BaseClassName):<statement-1>...<statement-N>
2. 多態的概念
????????多態是面向對象編程中一個重要的概念,它描述了一個函數或方法能夠對不同類型參數進行操作的能力。這種能力使得程序更加靈活和可擴展,因為它允許相同的接口可以用于不同的數據類型。
- 多態指不同對象對同一方法的不同實現。
- 子類可以覆蓋或擴展父類的方法。
3. 重寫方法
- 在子類中重新定義父類的方法,以改變其行為。
- 使用
super()
函數調用父類的方法。
#!/usr/bin/python3class Parent: # 定義父類def myMethod(self):print ('調用父類方法')class Child(Parent): # 定義子類def myMethod(self):print ('調用子類方法')c = Child() # 子類實例
c.myMethod() # 子類調用重寫方法
super(Child,c).myMethod() #用子類對象調用父類已被覆蓋的方法
四、實戰演示:設計面向對象程序
1. 模擬現實世界問題
- 以設計一個圖書館管理系統為例,展示如何抽象出類和對象。
- 創建
Book
、Member
、Librarian
等類。
2. 利用OOP特性解決問題
- 使用繼承創建
Novel
和Textbook
類,它們都繼承自Book
類。 - 實現多態,如不同類型的書籍有不同的借閱規則。
3. 設計用戶界面
- 演示如何為圖書館系統設計簡單的文本界面。
- 通過創建
LibrarySystem
類,管理圖書和會員的交互。
class LibrarySystem:def __init__(self):self.books = {} # key: book_id, value: book_titleself.members = {} # key: member_id, value: member_nameself.borrowed_books = {} # key: member_id, value: list of borrowed book_idsdef add_book(self, book_id, book_title):if book_id in self.books:print(f"Book '{book_title}' with ID {book_id} already exists.")else:self.books[book_id] = book_titleprint(f"Book '{book_title}' has been added with ID {book_id}.")def register_member(self, member_id, member_name):if member_id in self.members:print(f"Member '{member_name}' with ID {member_id} already registered.")else:self.members[member_id] = member_nameself.borrowed_books[member_id] = []print(f"Member '{member_name}' has been registered with ID {member_id}.")def borrow_book(self, member_id, book_id):if book_id not in self.books:print(f"Book with ID {book_id} does not exist.")elif member_id not in self.members:print(f"Member with ID {member_id} is not registered.")elif book_id in self.borrowed_books[member_id]:print(f"Member '{self.members[member_id]}' has already borrowed the book '{self.books[book_id]}' with ID {book_id}.")else:self.borrowed_books[member_id].append(book_id)print(f"Member '{self.members[member_id]}' has borrowed the book '{self.books[book_id]}' with ID {book_id}.")def return_book(self, member_id, book_id):if book_id not in self.books:print(f"Book with ID {book_id} does not exist.")elif member_id not in self.members:print(f"Member with ID {member_id} is not registered.")elif book_id not in self.borrowed_books[member_id]:print(f"Member '{self.members[member_id]}' did not borrow the book '{self.books[book_id]}' with ID {book_id}.")else:self.borrowed_books[member_id].remove(book_id)print(f"Member '{self.members[member_id]}' has returned the book '{self.books[book_id]}' with ID {book_id}.")def run(self):while True:print("\nWelcome to the Library System")print("1. Add a book")print("2. Register a member")print("3. Borrow a book")print("4. Return a book")print("5. Exit")choice = input("Enter your choice: ")if choice == "1":book_id = input("Enter book ID: ")book_title = input("Enter book title: ")self.add_book(book_id, book_title)elif choice == "2":member_id = input("Enter member ID: ")member_name = input("Enter member name: ")self.register_member(member_id, member_name)elif choice == "3":member_id = input("Enter member ID: ")book_id = input("Enter book ID: ")self.borrow_book(member_id, book_id)elif choice == "4":member_id = input("Enter member ID: ")book_id = input("Enter book ID: ")self.return_book(member_id, book_id)elif choice == "5":print("Exiting the Library System.")breakelse:print("Invalid choice. Please enter a number between 1 and 5.")# Create an instance of LibrarySystem and run it
library_system = LibrarySystem()
library_system.run()
五、總結
????????至此,我們深入探討了Python中的面向對象編程,學習了類和對象、繼承、封裝和多態等核心概念。通過實際案例,我們了解了如何運用這些概念解決實際問題,并體驗了編程的另一種范式。繼續前進,我們將探索Python的異常處理和文件操作,使程序更加健壯和實用。