目录

前言

一、核心概念:类、对象、属性与方法

1. 类(Class):对象的蓝图

2. 对象(Object):类的实例

3. 属性(Attribute):对象的数据

4. 方法(Method):对象的行为

二、封装:隐藏实现细节,保护数据

1. 访问控制:公有、私有和受保护

2. 属性装饰器:优雅控制属性访问

三、继承:代码复用与层次化设计

1. 单继承:子类继承父类的属性和方法

2. 多继承:子类从多个父类继承

3. 方法解析顺序(MRO)

四、多态:同一接口,不同实现

1. 方法重写(Override)

2. 鸭子类型(Duck Typing)

五、特殊方法:让类更强大

1. 构造与析构方法

2. 字符串表示方法

3. 运算符重载

六、抽象基类与接口

1. 抽象基类(ABC)

2. 协议(Protocol):静态鸭子类型(Python 3.8+)

七、设计模式:面向对象的最佳实践

1. 单例模式:确保类只有一个实例

2. 工厂模式:通过工厂方法创建对象

八、高级技巧

1. 类属性与实例属性的动态绑定

2. 元类(Metaclass)

总结


前言

Python 作为一门多范式编程语言,面向对象编程(Object-Oriented Programming, OOP)是其核心特性之一。本文将从基础概念到高级技巧,全面解析 Python 的面向对象编程,帮助你构建更清晰、更易维护的代码结构。

一、核心概念:类、对象、属性与方法

1. 类(Class):对象的蓝图

类是创建对象的模板,定义了对象的属性和方法。

class Person:
    # 类属性(所有实例共享)
    species = "Human"
    
    # 构造方法:初始化实例属性
    def __init__(self, name, age):
        self.name = name  # 实例属性
        self.age = age
    
    # 实例方法:操作实例属性
    def greet(self):
        return f"Hello, my name is {self.name} and I'm {self.age} years old."

2. 对象(Object):类的实例

通过类创建具体的对象实例。

# 创建对象
p1 = Person("Alice", 30)
p2 = Person("Bob", 25)

# 访问属性和方法
print(p1.name)      # Alice
print(p1.greet())   # Hello, my name is Alice and I'm 30 years old.
print(p1.species)   # Human(类属性)

3. 属性(Attribute):对象的数据

  • 类属性:所有实例共享,定义在类中但方法外。
  • 实例属性:每个实例独有,通过self绑定。

4. 方法(Method):对象的行为

  • 实例方法:第一个参数是self,操作实例属性。
  • 类方法:用@classmethod装饰,第一个参数是cls,操作类属性。
  • 静态方法:用@staticmethod装饰,无默认参数,与类关联但不操作属性。

二、封装:隐藏实现细节,保护数据

1. 访问控制:公有、私有和受保护

Python 通过命名约定实现访问控制:

  • 公有属性 / 方法:无特殊前缀(如name)。
  • 私有属性 / 方法:以双下划线开头(如__private_attr)。
  • 受保护属性 / 方法:以单下划线开头(如_protected_attr),约定不直接访问。

class BankAccount:
    def __init__(self, balance):
        self.__balance = balance  # 私有属性
    
    def deposit(self, amount):
        self.__balance += amount
    
    def withdraw(self, amount):
        if amount > self.__balance:
            raise ValueError("Insufficient funds")
        self.__balance -= amount
    
    def get_balance(self):  # 公有方法访问私有属性
        return self.__balance

# 使用示例
account = BankAccount(1000)
account.deposit(500)
account.withdraw(300)
print(account.get_balance())  # 1200
# print(account.__balance)    # 报错:AttributeError

2. 属性装饰器:优雅控制属性访问

使用@property@setter@deleter装饰器管理属性。

class Person:
    def __init__(self, age):
        self.__age = age
    
    @property
    def age(self):  # 只读属性
        return self.__age
    
    @age.setter
    def age(self, value):  # 可写属性
        if value < 0:
            raise ValueError("Age cannot be negative")
        self.__age = value

# 使用示例
p = Person(25)
print(p.age)  # 25
p.age = 30    # 调用@age.setter
# p.age = -5  # 报错:ValueError

三、继承:代码复用与层次化设计

1. 单继承:子类继承父类的属性和方法

class Animal:
    def __init__(self, name):
        self.name = name
    
    def speak(self):
        raise NotImplementedError("Subclass must implement this method")

class Dog(Animal):
    def speak(self):  # 方法重写
        return f"{self.name} says Woof!"

class Cat(Animal):
    def speak(self):
        return f"{self.name} says Meow!"

# 使用示例
dog = Dog("Buddy")
cat = Cat("Whiskers")
print(dog.speak())  # Buddy says Woof!
print(cat.speak())  # Whiskers says Meow!

2. 多继承:子类从多个父类继承

class Flyable:
    def fly(self):
        return "Flying..."

class Swimmable:
    def swim(self):
        return "Swimming..."

class Duck(Flyable, Swimmable):  # 多继承
    pass

# 使用示例
duck = Duck()
print(duck.fly())  # Flying...
print(duck.swim()) # Swimming...

3. 方法解析顺序(MRO)

多继承时,Python 通过 C3 线性化算法确定方法调用顺序。

print(Duck.mro())  # 查看MRO
# 输出:[__main__.Duck, __main__.Flyable, __main__.Swimmable, object]

四、多态:同一接口,不同实现

1. 方法重写(Override)

子类重新定义父类的方法。

class Shape:
    def area(self):
        return 0

class Rectangle(Shape):
    def __init__(self, width, height):
        self.width = width
        self.height = height
    
    def area(self):  # 重写area方法
        return self.width * self.height

class Circle(Shape):
    def __init__(self, radius):
        self.radius = radius
    
    def area(self):  # 重写area方法
        return 3.14 * self.radius ** 2

# 使用示例
shapes = [Rectangle(3, 4), Circle(5)]
for shape in shapes:
    print(f"Area: {shape.area()}")  # 自动调用对应子类的area方法

2. 鸭子类型(Duck Typing)

不关心对象类型,只关心是否实现特定方法。

class Duck:
    def quack(self):
        return "Quack!"

class Person:
    def quack(self):
        return "I'm imitating a duck!"

# 接受任何实现了quack方法的对象
def make_quack(obj):
    print(obj.quack())

# 使用示例
duck = Duck()
person = Person()
make_quack(duck)    # Quack!
make_quack(person)  # I'm imitating a duck!

五、特殊方法:让类更强大

1. 构造与析构方法

  • __init__:对象初始化。
  • __del__:对象销毁时调用。

2. 字符串表示方法

  • __str__:用户友好的字符串表示。
  • __repr__:开发者友好的字符串表示。

class Point:
    def __init__(self, x, y):
        self.x = x
        self.y = y
    
    def __str__(self):
        return f"({self.x}, {self.y})"
    
    def __repr__(self):
        return f"Point({self.x}, {self.y})"

# 使用示例
p = Point(3, 4)
print(p)        # 调用__str__:(3, 4)
print(repr(p))  # 调用__repr__:Point(3, 4)

3. 运算符重载

通过特殊方法定义类的运算符行为。

class Vector:
    def __init__(self, x, y):
        self.x = x
        self.y = y
    
    def __add__(self, other):  # 重载+运算符
        return Vector(self.x + other.x, self.y + other.y)
    
    def __eq__(self, other):   # 重载==运算符
        return self.x == other.x and self.y == other.y

# 使用示例
v1 = Vector(1, 2)
v2 = Vector(3, 4)
v3 = v1 + v2  # 调用__add__
print(v3.x, v3.y)  # 4 6
print(v1 == v2)    # 调用__eq__:False

六、抽象基类与接口

1. 抽象基类(ABC)

定义抽象方法,强制子类实现。

from abc import ABC, abstractmethod

class Shape(ABC):  # 抽象基类
    @abstractmethod  # 抽象方法
    def area(self):
        pass

class Rectangle(Shape):
    def __init__(self, width, height):
        self.width = width
        self.height = height
    
    def area(self):  # 必须实现抽象方法
        return self.width * self.height

# r = Shape()  # 报错:不能实例化抽象类
r = Rectangle(3, 4)
print(r.area())  # 12

2. 协议(Protocol):静态鸭子类型(Python 3.8+)

from typing import Protocol

class Flyable(Protocol):  # 定义协议
    def fly(self) -> str:
        pass

class Bird:
    def fly(self):
        return "Flying with wings!"

class Plane:
    def fly(self):
        return "Flying with engines!"

# 接受任何实现了Flyable协议的对象
def let_it_fly(obj: Flyable):
    print(obj.fly())

# 使用示例
bird = Bird()
plane = Plane()
let_it_fly(bird)  # Flying with wings!
let_it_fly(plane) # Flying with engines!

七、设计模式:面向对象的最佳实践

1. 单例模式:确保类只有一个实例

class Singleton:
    _instance = None
    
    def __new__(cls, *args, **kwargs):
        if not cls._instance:
            cls._instance = super().__new__(cls)
        return cls._instance

# 使用示例
s1 = Singleton()
s2 = Singleton()
print(s1 is s2)  # True(同一个实例)

2. 工厂模式:通过工厂方法创建对象

class Animal:
    def speak(self):
        pass

class Dog(Animal):
    def speak(self):
        return "Woof!"

class Cat(Animal):
    def speak(self):
        return "Meow!"

class AnimalFactory:
    @staticmethod
    def create_animal(type):
        if type == "dog":
            return Dog()
        elif type == "cat":
            return Cat()
        else:
            raise ValueError("Invalid animal type")

# 使用示例
dog = AnimalFactory.create_animal("dog")
cat = AnimalFactory.create_animal("cat")
print(dog.speak())  # Woof!
print(cat.speak())  # Meow!

八、高级技巧

1. 类属性与实例属性的动态绑定

class Person:
    pass

p = Person()
p.name = "Alice"  # 动态绑定实例属性
Person.country = "China"  # 动态绑定类属性

print(p.name)       # Alice
print(p.country)    # China
print(Person.country)  # China

2. 元类(Metaclass)

控制类的创建过程。

class MyMeta(type):
    def __new__(cls, name, bases, attrs):
        # 添加默认属性
        attrs["version"] = "1.0"
        return super().__new__(cls, name, bases, attrs)

class MyClass(metaclass=MyMeta):
    pass

# 使用示例
obj = MyClass()
print(obj.version)  # 1.0

总结

Python 的面向对象编程通过封装、继承、多态和抽象四大特性,提供了强大而灵活的代码组织方式。掌握类、对象、属性和方法的基本概念,理解特殊方法和设计模式的应用,能够帮助你构建出高内聚、低耦合的高质量代码。

建议在实践中逐步应用这些概念,从简单的类开始,逐步过渡到复杂的继承结构和设计模式,最终形成自己的面向对象编程风格。

Logo

Agent 垂直技术社区,欢迎活跃、内容共建。

更多推荐