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/python3 class Complex: def __init__(self, realpart, imagpart): self.r = realpart self.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/python3
class 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_title
self.members = {} # key: member_id, value: member_name
self.borrowed_books = {} # key: member_id, value: list of borrowed book_ids
def 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_title
print(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_name
self.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.")
break
else:
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的异常处理和文件操作,使程序更加健壮和实用。