Python 面向对象编程(OOP)详解
面向对象编程是Python的核心特性之一,它通过**类(Class)和对象(Object)**来组织代码。
一、基本概念
1. 类与对象
python
# 定义类
class Dog:
# 类属性(所有实例共享)
species = "Canis familiaris"
# 初始化方法(构造函数)
def __init__(self, name, age):
# 实例属性(每个对象独立)
self.name = name
self.age = age
# 实例方法
def bark(self):
return f"{self.name} says: Woof!"
def get_info(self):
return f"{self.name} is {self.age} years old"
# 创建对象(实例化)
dog1 = Dog("Buddy", 3)
dog2 = Dog("Max", 5)
print(dog1.name) # Buddy
print(dog1.bark()) # Buddy says: Woof!
print(dog2.get_info()) # Max is 5 years old
print(Dog.species) # Canis familiaris
二、四大特性
1. 封装(Encapsulation)
python
class BankAccount:
def __init__(self, owner, balance=0):
self.owner = owner
self.__balance = balance # 私有属性(双下划线)
# Getter方法
def get_balance(self):
return self.__balance
# Setter方法
def deposit(self, amount):
if amount > 0:
self.__balance += amount
return True
return False
def withdraw(self, amount):
if 0 < amount <= self.__balance:
self.__balance -= amount
return True
return False
account = BankAccount("John", 1000)
print(account.owner) # John
# print(account.__balance) # 错误!私有属性不能直接访问
print(account.get_balance()) # 1000
account.deposit(500)
account.withdraw(200)
2. 继承(Inheritance)
python
# 父类(基类)
class Animal:
def __init__(self, name, age):
self.name = name
self.age = age
def speak(self):
raise NotImplementedError("子类必须实现此方法")
def info(self):
return f"{self.name}, {self.age} years old"
# 子类(派生类)
class Cat(Animal):
def __init__(self, name, age, color):
# 调用父类构造方法
super().__init__(name, age)
self.color = color
# 重写父类方法
def speak(self):
return "Meow!"
# 扩展方法
def purr(self):
return "Purrr..."
class Dog(Animal):
def __init__(self, name, age, breed):
super().__init__(name, age)
self.breed = breed
def speak(self):
return "Woof!"
# 使用多态
animals = [Cat("Whiskers", 2, "white"), Dog("Rex", 3, "Golden Retriever")]
for animal in animals:
print(f"{animal.name}: {animal.speak()}")
3. 多态(Polymorphism)
python
class Shape:
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
class Circle(Shape):
def __init__(self, radius):
self.radius = radius
def area(self):
import math
return math.pi * self.radius ** 2
# 多态示例
shapes = [Rectangle(4, 5), Circle(3)]
for shape in shapes:
print(f"Area: {shape.area():.2f}")
4. 抽象(Abstraction)
python
from abc import ABC, abstractmethod
# 抽象基类
class Vehicle(ABC):
@abstractmethod
def start(self):
pass
@abstractmethod
def stop(self):
pass
# 具体方法
def fuel_type(self):
return "Gasoline"
class Car(Vehicle):
def start(self):
return "Car engine started"
def stop(self):
return "Car engine stopped"
class ElectricCar(Vehicle):
def start(self):
return "Electric car activated"
def stop(self):
return "Electric car deactivated"
def fuel_type(self):
return "Electricity"
# car = Vehicle() # 错误!不能实例化抽象类
tesla = ElectricCar()
print(tesla.start()) # Electric car activated
print(tesla.fuel_type()) # Electricity
三、高级特性
1. 类方法和静态方法
python
class MyClass:
class_variable = 0
def __init__(self, value):
self.value = value
# 实例方法
def instance_method(self):
return f"实例方法访问实例属性: {self.value}"
# 类方法
@classmethod
def class_method(cls):
cls.class_variable += 1
return f"类方法访问类属性: {cls.class_variable}"
# 静态方法
@staticmethod
def static_method():
return "静态方法,不访问类或实例属性"
obj = MyClass(10)
print(obj.instance_method()) # 实例方法访问实例属性: 10
print(MyClass.class_method()) # 类方法访问类属性: 1
print(MyClass.static_method())# 静态方法,不访问类或实例属性
2. 属性装饰器(Property)
python
class Person:
def __init__(self, name, age):
self._name = name
self._age = age
@property
def name(self):
return self._name
@name.setter
def name(self, value):
if not value:
raise ValueError("Name cannot be empty")
self._name = value
@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
@property
def is_adult(self):
return self._age >= 18
person = Person("Alice", 25)
print(person.name) # Alice
person.name = "Bob" # 使用setter
print(person.name) # Bob
print(person.is_adult) # True(只读属性)
3. 特殊方法(魔术方法)
python
class Vector:
def __init__(self, x, y):
self.x = x
self.y = y
# 字符串表示
def __str__(self):
return f"Vector({self.x}, {self.y})"
def __repr__(self):
return f"Vector({self.x}, {self.y})"
# 运算符重载
def __add__(self, other):
return Vector(self.x + other.x, self.y + other.y)
def __sub__(self, other):
return Vector(self.x - other.x, self.y - other.y)
def __mul__(self, scalar):
return Vector(self.x * scalar, self.y * scalar)
# 比较运算符
def __eq__(self, other):
return self.x == other.x and self.y == other.y
# 长度
def __len__(self):
return 2
# 迭代器
def __iter__(self):
return iter([self.x, self.y])
v1 = Vector(2, 3)
v2 = Vector(4, 5)
print(v1 + v2) # Vector(6, 8)
print(v1 * 3) # Vector(6, 9)
print(v1 == v2) # False
for coord in v1:
print(coord) # 2, 3
四、多重继承和MRO
python
class A:
def method(self):
return "A.method"
class B(A):
def method(self):
return "B.method"
class C(A):
def method(self):
return "C.method"
class D(B, C):
pass
d = D()
print(d.method()) # B.method(按MRO顺序)
print(D.__mro__) # 方法解析顺序
# (<class '__main__.D'>, <class '__main__.B'>, <class '__main__.C'>,
# <class '__main__.A'>, <class 'object'>)
五、装饰器在类中的应用
python
# 类装饰器
def add_method(cls):
def new_method(self):
return "Added by decorator"
cls.added_method = new_method
return cls
@add_method
class MyClass:
def original_method(self):
return "Original"
obj = MyClass()
print(obj.original_method()) # Original
print(obj.added_method()) # Added by decorator
# 方法装饰器
def log_method(func):
def wrapper(self, *args, **kwargs):
print(f"Calling {func.__name__}")
return func(self, *args, **kwargs)
return wrapper
class Calculator:
@log_method
def add(self, a, b):
return a + b
@log_method
def multiply(self, a, b):
return a * b
calc = Calculator()
print(calc.add(2, 3)) # Calling add \n 5
六、数据类(Python 3.7+)
python
from dataclasses import dataclass, field
from typing import List
@dataclass
class Person:
name: str
age: int = 0 # 默认值
hobbies: List[str] = field(default_factory=list)
@property
def is_adult(self):
return self.age >= 18
# 自动生成 __init__, __repr__, __eq__ 等方法
p1 = Person("Alice", 25, ["reading", "swimming"])
p2 = Person("Bob", 30)
p3 = Person("Alice", 25, ["reading", "swimming"])
print(p1) # Person(name='Alice', age=25, hobbies=['reading', 'swimming'])
print(p1 == p3) # True
print(p2.is_adult) # True
七、最佳实践
1. 组合优于继承
python
class Engine:
def start(self):
return "Engine started"
class Wheels:
def rotate(self):
return "Wheels rotating"
class Car:
def __init__(self):
self.engine = Engine()
self.wheels = [Wheels() for _ in range(4)]
def drive(self):
return f"{self.engine.start()} and {self.wheels[0].rotate()}"
car = Car()
print(car.drive()) # Engine started and Wheels rotating
2. 单例模式
python
class Singleton:
_instance = None
def __new__(cls):
if cls._instance is None:
cls._instance = super().__new__(cls)
return cls._instance
def __init__(self):
self.data = []
s1 = Singleton()
s1.data.append(1)
s2 = Singleton()
print(s2.data) # [1](同一个实例)
print(s1 is s2) # True
3. 工厂模式
python
class AnimalFactory:
@staticmethod
def create_animal(animal_type, *args, **kwargs):
if animal_type == "dog":
return Dog(*args, **kwargs)
elif animal_type == "cat":
return Cat(*args, **kwargs)
elif animal_type == "bird":
return Bird(*args, **kwargs)
else:
raise ValueError(f"Unknown animal type: {animal_type}")
animal = AnimalFactory.create_animal("dog", "Rex", 3, "German Shepherd")
八、实用技巧
1. 动态创建类
python
# type() 动态创建类
MyClass = type('MyClass', (), {'x': 10, 'greet': lambda self: "Hello"})
obj = MyClass()
print(obj.x) # 10
print(obj.greet()) # Hello
2. 枚举类
python
from enum import Enum, auto
class Color(Enum):
RED = auto()
GREEN = auto()
BLUE = auto()
print(Color.RED) # Color.RED
print(Color.RED.value) # 1
3. 命名元组
python
from collections import namedtuple
Point = namedtuple('Point', ['x', 'y'])
p = Point(10, 20)
print(p.x, p.y) # 10 20
print(p._asdict()) # {'x': 10, 'y': 20}
面向对象编程的核心思想是将数据和方法封装在对象中,通过对象间的交互来构建复杂的程序。合理使用OOP可以提高代码的可维护性 、可重用性 和可扩展性。