Python面向对象编程详解
1. 什么是面向对象编程
面向对象编程(OOP)是一种编程范式,它使用"对象"来设计应用程序。对象可以包含数据(属性)和代码(方法)。Python作为一门支持OOP的语言,提供了完整的面向对象特性,包括封装、继承和多态。
2. 类和对象
类是创建对象的蓝图,定义了一组属性和方法。对象是类的实例。
定义类的基本语法:
class Person:
# 类属性
species = 'Homo sapiens'
# 初始化方法(构造函数)
def __init__(self, name, age):
# 实例属性
self.name = name
self.age = age
# 实例方法
def introduce(self):
return f"My name is {self.name}, I'm {self.age} years old."
# 类方法
@classmethod
def get_species(cls):
return f"Our species is {cls.species}."
创建对象(实例化):
# 创建Person类的实例
person1 = Person("Alice", 25)
person2 = Person("Bob", 30)
# 访问实例属性
print(person1.name) # 输出: Alice
print(person2.age) # 输出: 30
# 调用实例方法
print(person1.introduce()) # 输出: My name is Alice, I'm 25 years old.
# 调用类方法
print(Person.get_species()) # 输出: Our species is Homo sapiens.
3. 继承
继承允许我们创建一个新类,从现有类继承属性和方法,从而实现代码重用。
定义子类:
class Student(Person):
def __init__(self, name, age, student_id):
# 调用父类的初始化方法
super().__init__(name, age)
self.student_id = student_id
# 重写父类方法
def introduce(self):
return f"{super().introduce()} My student ID is {self.student_id}."
# 新增方法
def study(self, subject):
return f"{self.name} is studying {subject}."
使用子类:
student = Student("Charlie", 20, "S12345")
print(student.introduce()) # 输出: My name is Charlie, I'm 20 years old. My student ID is S12345.
print(student.study("Math")) # 输出: Charlie is studying Math.
4. 封装
封装是指将数据和方法包装在类中,并限制对对象内部状态的直接访问。
使用私有属性和方法(以双下划线开头):
class BankAccount:
def __init__(self, owner, balance):
self.owner = owner
self.__balance = balance # 私有属性
def deposit(self, amount):
if amount > 0:
self.__balance += amount
return f"Deposited ${amount}. New balance: ${self.__balance}"
return "Invalid deposit amount."
def withdraw(self, amount):
if 0 < amount <= self.__balance:
self.__balance -= amount
return f"Withdrew ${amount}. Remaining balance: ${self.__balance}"
return "Invalid withdrawal amount."
def get_balance(self):
return self.__balance # 通过方法访问私有属性
使用封装类:
account = BankAccount("David", 1000)
print(account.deposit(500)) # 输出: Deposited $500. New balance: $1500
print(account.withdraw(200)) # 输出: Withdrew $200. Remaining balance: $1300
# 尝试直接访问私有属性会报错
# print(account.__balance) # AttributeError: 'BankAccount' object has no attribute '__balance'
# 通过方法访问
print(account.get_balance()) # 输出: 1300
5. 多态
多态允许不同类的对象对相同消息(方法调用)做出不同响应。
实现多态的例子:
class Animal:
def speak(self):
raise NotImplementedError("Subclass must implement this method")
class Dog(Animal):
def speak(self):
return "Woof!"
class Cat(Animal):
def speak(self):
return "Meow!"
class Duck(Animal):
def speak(self):
return "Quack!"
# 多态函数
def animal_sound(animal):
return animal.speak()
使用多态:
dog = Dog()
cat = Cat()
duck = Duck()
print(animal_sound(dog)) # 输出: Woof!
print(animal_sound(cat)) # 输出: Meow!
print(animal_sound(duck)) # 输出: Quack!
6. 特殊方法(魔术方法)
特殊方法以双下划线开头和结尾,允许自定义类的行为。
常用特殊方法示例:
class Vector:
def __init__(self, x, y):
self.x = x
self.y = y
# 字符串表示
def __str__(self):
return f"Vector({self.x}, {self.y})"
# 加法运算符重载
def __add__(self, other):
if isinstance(other, Vector):
return Vector(self.x + other.x, self.y + other.y)
return NotImplemented
# 等于运算符重载
def __eq__(self, other):
if isinstance(other, Vector):
return self.x == other.x and self.y == other.y
return False
# 小于运算符重载
def __lt__(self, other):
if isinstance(other, Vector):
return (self.x ** 2 + self.y ** 2) < (other.x ** 2 + other.y ** 2)
return NotImplemented
使用特殊方法:
v1 = Vector(3, 4)
v2 = Vector(1, 2)
v3 = Vector(3, 4)
print(v1) # 输出: Vector(3, 4)
print(v1 + v2) # 输出: Vector(4, 6)
print(v1 == v3) # 输出: True
print(v1 < v2) # 输出: False
7. 静态方法和类方法
静态方法不接收类或实例作为第一个参数,行为类似于普通函数。
类方法接收类作为第一个参数(通常命名为cls)。
class MathUtils:
# 静态方法
@staticmethod
def add(a, b):
return a + b
# 类方法
@classmethod
def multiply(cls, a, b):
# 类方法可以访问类属性
result = a * b
print(f"Using {cls.__name__} to multiply {a} and {b}")
return result
使用静态方法和类方法:
print(MathUtils.add(5, 3)) # 输出: 8
print(MathUtils.multiply(4, 6)) # 输出: Using MathUtils to multiply 4 and 6 然后输出: 24
8. 属性访问控制
使用@property装饰器可以创建只读属性或对属性访问添加逻辑。
class Person:
def __init__(self, first_name, last_name):
self.first_name = first_name
self._last_name = last_name # 约定俗成的受保护属性
@property
def full_name(self):
"""只读属性:全名"""
return f"{self.first_name} {self._last_name}"
@property
def last_name(self):
"""带验证的属性访问"""
return self._last_name
@last_name.setter
def last_name(self, value):
"""属性设置器"""
if not value:
raise ValueError("Last name cannot be empty")
self._last_name = value
使用属性访问控制:
person = Person("John", "Doe")
print(person.full_name) # 输出: John Doe
# 修改姓氏
person.last_name = "Smith"
print(person.full_name) # 输出: John Smith
# 尝试设置无效值
try:
person.last_name = ""
except ValueError as e:
print(e) # 输出: Last name cannot be empty
9. 抽象基类
抽象基类(ABC)定义接口规范,子类必须实现所有抽象方法。
from abc import ABC, abstractmethod
class Shape(ABC):
@abstractmethod
def area(self):
pass
@abstractmethod
def perimeter(self):
pass
def describe(self):
return "This is a shape"
class Circle(Shape):
def __init__(self, radius):
self.radius = radius
def area(self):
return 3.14 * self.radius ** 2
def perimeter(self):
return 2 * 3.14 * self.radius
使用抽象基类:
circle = Circle(5)
print(circle.area()) # 输出: 78.5
print(circle.perimeter()) # 输出: 31.400000000000002
print(circle.describe()) # 输出: This is a shape
# 尝试实例化抽象基类会报错
try:
shape = Shape()
except TypeError as e:
print(e) # 输出: Can't instantiate abstract class Shape with abstract methods area, perimeter
10. 总结
Python面向对象编程提供了强大的工具来组织代码、提高可重用性和可维护性。通过类和对象、继承、封装、多态等核心概念,以及特殊方法、属性访问控制和抽象基类等高级特性,我们可以构建灵活且结构良好的应用程序。掌握这些OOP原则和Python实现方式,将帮助你编写更清晰、更高效的代码,并在大型项目中更好地管理复杂性。
声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。







