面向对象编程 是 Python 编程的核心思想,它能将现实世界的事物抽象为代码中的类和对象,让复杂程序变得条理清晰、易于维护。掌握面向对象,你才能真正写出专业级的 Python 代码。
1. 面向对象编程基础
面向对象编程(OOP) 是一种编程范式,它将数据和操作数据的方法组织在一起,形成“对象”。
# 传统过程式编程:数据和函数分离data = [1, 2, 3, 4, 5]defcalculate_average(numbers):return sum(numbers) / len(numbers)# 面向对象编程:数据和方法封装在一起classDataProcessor:def__init__(self, data): self.data = datadefcalculate_average(self):return sum(self.data) / len(self.data)# 明显看出OOP的封装优势
2. 类和对象的创建与使用
类 是对象的蓝图,对象 是类的实例
# 定义一个简单的学生类classStudent:# __init__是特殊的初始化方法(构造方法)# self代表类的实例本身def__init__(self, name, age, student_id):"""初始化学生对象的属性""" self.name = name # 实例属性 self.age = age self.student_id = student_id self.grades = [] # 初始化为空列表# 实例方法:操作对象数据的方法defadd_grade(self, grade):"""添加成绩""" self.grades.append(grade)defget_average(self):"""计算平均分"""ifnot self.grades:return0return sum(self.grades) / len(self.grades)defdisplay_info(self):"""显示学生信息""" avg = self.get_average() print(f"学生姓名:{self.name}") print(f"学号:{self.student_id}") print(f"年龄:{self.age}") print(f"平均成绩:{avg:.2f}")# 创建对象(类的实例)student1 = Student("张三", 20, "2023001")student2 = Student("李四", 21, "2023002")# 使用对象的方法student1.add_grade(85)student1.add_grade(90)student1.add_grade(78)student1.display_info()
3. 实例属性、类属性和私有属性
classBankAccount:# 类属性:所有对象共享 bank_name = "中国银行" total_accounts = 0def__init__(self, owner, initial_balance=0):"""初始化银行账户"""# 实例属性:每个对象独有 self.owner = owner self.__balance = initial_balance # 私有属性,双下划线开头# 修改类属性 BankAccount.total_accounts += 1 self.account_id = BankAccount.total_accounts# 属性访问器(getter) @propertydefbalance(self):"""获取余额(只读)"""return self.__balance# 属性修改器(setter) @balance.setterdefbalance(self, value):"""设置余额,添加验证逻辑"""if value < 0: print("错误:余额不能为负数")else: self.__balance = valuedefdeposit(self, amount):"""存款"""if amount > 0: self.__balance += amount print(f"存款成功!当前余额:{self.__balance}")else: print("存款金额必须大于0")defwithdraw(self, amount):"""取款"""if0 < amount <= self.__balance: self.__balance -= amount print(f"取款成功!当前余额:{self.__balance}")returnTrueelse: print("取款失败:余额不足或金额无效")returnFalse @classmethoddefget_bank_info(cls):"""类方法:操作类属性""" print(f"银行名称:{cls.bank_name}") print(f"总账户数:{cls.total_accounts}") @staticmethoddefcalculate_interest(principal, rate, years):"""静态方法:不依赖类和实例"""return principal * (1 + rate) ** years - principal# 使用示例account1 = BankAccount("张三", 1000)account2 = BankAccount("李四", 500)print(f"银行名称:{BankAccount.bank_name}")print(f"账户1余额:{account1.balance}") # 通过property访问account1.deposit(500)account1.withdraw(200)BankAccount.get_bank_info()
4. 继承与多态
继承 允许我们创建新类时重用现有类的功能, 多态 让不同的类对象可以响应相同的方法调用。
# 基类(父类)classAnimal:def__init__(self, name, age): self.name = name self.age = agedefmake_sound(self):"""动物叫声(抽象方法,子类必须实现)"""raise NotImplementedError("子类必须实现make_sound方法")defeat(self):"""动物进食""" print(f"{self.name}正在吃东西")defsleep(self):"""动物睡觉""" print(f"{self.name}正在睡觉")# 继承Animal类classDog(Animal):def__init__(self, name, age, breed):# 调用父类的初始化方法 super().__init__(name, age) self.breed = breed # 子类特有属性# 方法重写(多态)defmake_sound(self): print(f"{self.name}在汪汪叫!")# 子类特有方法deffetch(self): print(f"{self.name}正在捡球")classCat(Animal):def__init__(self, name, age, color): super().__init__(name, age) self.color = colordefmake_sound(self): print(f"{self.name}在喵喵叫!")defclimb_tree(self): print(f"{self.name}正在爬树")classBird(Animal):def__init__(self, name, age, wing_span): super().__init__(name, age) self.wing_span = wing_spandefmake_sound(self): print(f"{self.name}在叽叽喳喳!")deffly(self): print(f"{self.name}正在飞翔")# 演示:不同对象调用相同方法,表现不同行为defanimal_concert(animals):"""动物音乐会""" print("=== 动物音乐会开始 ===")for animal in animals: animal.make_sound() print("=== 音乐会结束 ===\n")# 创建不同动物的实例animals = [ Dog("旺财", 3, "金毛"), Cat("咪咪", 2, "白色"), Bird("小翠", 1, 0.3)]# 多态animal_concert(animals)# 继承的功能for animal in animals: animal.eat() # 继承自父类的方法 animal.sleep()# 检查类型并调用特有方法if isinstance(animal, Dog): animal.fetch()elif isinstance(animal, Cat): animal.climb_tree()elif isinstance(animal, Bird): animal.fly() print("-" * 30)
5. 多层继承和方法
# 多层继承classPerson:def__init__(self, name, gender): self.name = name self.gender = genderdefintroduce(self): print(f"我是{self.name},性别{self.gender}")classEmployee(Person):def__init__(self, name, gender, employee_id): super().__init__(name, gender) self.employee_id = employee_id self.salary = 0defset_salary(self, salary): self.salary = salarydefintroduce(self): super().introduce() print(f"工号:{self.employee_id}")classManager(Employee):def__init__(self, name, gender, employee_id, department): super().__init__(name, gender, employee_id) self.department = department self.team = []defadd_team_member(self, employee): self.team.append(employee)defintroduce(self): super().introduce() print(f"部门:{self.department}") print(f"团队人数:{len(self.team)}")# 使用方法解析顺序print("Manager类的MRO:", Manager.__mro__)manager = Manager("王经理", "男", "M001", "技术部")employee1 = Employee("张三", "男", "E001")employee2 = Employee("李四", "女", "E002")manager.add_team_member(employee1)manager.add_team_member(employee2)manager.introduce()
6. 综合示例
"""图书管理系统功能:1. 图书的添加、删除、查询2. 读者的注册、借书、还书3. 借阅记录管理"""classBook:"""图书类""" total_books = 0def__init__(self, title, author, isbn, total_copies=1): self.title = title self.author = author self.isbn = isbn self.total_copies = total_copies self.available_copies = total_copies Book.total_books += 1 self.book_id = Book.total_booksdefborrow(self):"""借书"""if self.available_copies > 0: self.available_copies -= 1returnTruereturnFalsedefreturn_book(self):"""还书"""if self.available_copies < self.total_copies: self.available_copies += 1returnTruereturnFalsedefget_status(self):"""获取图书状态"""return {'title': self.title,'author': self.author,'isbn': self.isbn,'total': self.total_copies,'available': self.available_copies }def__str__(self):"""字符串表示""" status = "可借"if self.available_copies > 0else"已借完"returnf"《{self.title}》- {self.author} [{status}]"classReader:"""读者类"""def__init__(self, name, reader_id): self.name = name self.reader_id = reader_id self.borrowed_books = [] # 借阅的图书ISBN列表 self.max_books = 5# 最大借阅数量defcan_borrow_more(self):"""检查是否可以继续借书"""return len(self.borrowed_books) < self.max_booksdefborrow_book(self, book_isbn):"""借书"""if self.can_borrow_more(): self.borrowed_books.append(book_isbn)returnTruereturnFalsedefreturn_book(self, book_isbn):"""还书"""if book_isbn in self.borrowed_books: self.borrowed_books.remove(book_isbn)returnTruereturnFalsedef__str__(self):returnf"读者:{self.name} (ID: {self.reader_id})"classLibrary:"""图书馆类"""def__init__(self, name): self.name = name self.books = {} # ISBN: Book对象 self.readers = {} # reader_id: Reader对象 self.borrow_records = [] # 借阅记录defadd_book(self, title, author, isbn, copies=1):"""添加图书"""if isbn in self.books:# 如果图书已存在,增加副本 self.books[isbn].total_copies += copies self.books[isbn].available_copies += copieselse:# 创建新图书 self.books[isbn] = Book(title, author, isbn, copies) print(f"成功添加图书:{title}")defregister_reader(self, name, reader_id):"""注册读者"""if reader_id in self.readers: print(f"读者ID {reader_id} 已存在")returnFalse self.readers[reader_id] = Reader(name, reader_id) print(f"读者 {name} 注册成功")returnTruedefborrow_book(self, reader_id, isbn):"""借书操作"""# 检查读者是否存在if reader_id notin self.readers: print("读者不存在")returnFalse# 检查图书是否存在if isbn notin self.books: print("图书不存在")returnFalse reader = self.readers[reader_id] book = self.books[isbn]# 检查是否可以借阅ifnot reader.can_borrow_more(): print(f"{reader.name} 已达到最大借阅数量")returnFalseifnot book.borrow(): print(f"《{book.title}》 已全部借出")returnFalse# 记录借阅if reader.borrow_book(isbn): self.borrow_records.append({'reader_id': reader_id,'isbn': isbn,'date': '2024-01-01', # 简化处理'action': 'borrow' }) print(f"{reader.name} 成功借阅 《{book.title}》")returnTruereturnFalsedefreturn_book(self, reader_id, isbn):"""还书操作"""if reader_id notin self.readers or isbn notin self.books:returnFalse reader = self.readers[reader_id] book = self.books[isbn]if reader.return_book(isbn) and book.return_book(): self.borrow_records.append({'reader_id': reader_id,'isbn': isbn,'date': '2024-01-02','action': 'return' }) print(f"{reader.name} 成功归还 《{book.title}》")returnTrue print("还书失败")returnFalsedefsearch_book(self, keyword):"""搜索图书""" results = [] keyword = keyword.lower()for isbn, book in self.books.items():if (keyword in book.title.lower() or keyword in book.author.lower() or keyword in isbn.lower()): results.append(book)return resultsdefshow_status(self):"""显示图书馆状态""" print(f"\n=== {self.name} 状态报告 ===") print(f"图书总数:{len(self.books)} 种") print(f"注册读者:{len(self.readers)} 人") print(f"借阅记录:{len(self.borrow_records)} 条")# 显示可借图书 available_books = [b for b in self.books.values() if b.available_copies > 0] print(f"可借图书:{len(available_books)} 种")# 显示借阅最多的图书if self.borrow_records: borrow_counts = {}for record in self.borrow_records:if record['action'] == 'borrow': borrow_counts[record['isbn']] = borrow_counts.get(record['isbn'], 0) + 1if borrow_counts: most_borrowed_isbn = max(borrow_counts, key=borrow_counts.get) most_borrowed_book = self.books[most_borrowed_isbn] print(f"最受欢迎图书:{most_borrowed_book.title} "f"(借阅{borrow_counts[most_borrowed_isbn]}次)")# 运行示例defmain():"""主程序"""# 创建图书馆 library = Library("城市图书馆")# 添加图书 library.add_book("Python编程从入门到实践", "Eric Matthes", "978-7-115-42802-8", 3) library.add_book("流畅的Python", "Luciano Ramalho", "978-7-115-45415-7", 2) library.add_book("算法导论", "Thomas H. Cormen", "978-7-111-40701-0", 1)# 注册读者 library.register_reader("张三", "R001") library.register_reader("李四", "R002")# 借书操作 print("\n=== 借书操作 ===") library.borrow_book("R001", "978-7-115-42802-8") library.borrow_book("R001", "978-7-115-45415-7") library.borrow_book("R002", "978-7-115-42802-8")# 搜索图书 print("\n=== 搜索图书 ===") results = library.search_book("python")for book in results: print(f"找到:{book}")# 显示状态 library.show_status()# 还书操作 print("\n=== 还书操作 ===") library.return_book("R001", "978-7-115-42802-8")# 最终状态 library.show_status()if __name__ == "__main__": main()
7. 总结
- 面向对象的优势 :OOP让代码更模块化、可重用、易维护。当项目复杂度增加时,面向对象的优势会越来越明显。
- 合理使用继承 :优先使用组合而非继承,除非有明显的"是一个"关系
- 注意
self 参数 :实例方法第一个参数必须是 self - 私有属性约定 :Python没有真正的私有属性,双下划线只是名称改写