Python 面向对象

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可以提高代码的可维护性可重用性可扩展性

相关推荐
JIngJaneIL6 小时前
基于Java + vue干洗店预约洗衣系统(源码+数据库+文档)
java·开发语言·前端·数据库·vue.js·spring boot
BoBoZz197 小时前
AlignTwoPolyDatas 基于ICP算法的配准和相机视角切换
python·vtk·图形渲染·图形处理
dllmayday7 小时前
Qt/QML + C++ 双向数据绑定(MVVM 模式的几种常用方法(ChatGPT)
开发语言·c++·qt
han_hanker7 小时前
统一拦截异常 @RestControllerAdvice
java·开发语言·数据库
嗝o゚7 小时前
Flutter与开源鸿蒙:一场“应用定义权”的静默战争,与开发者的“范式跃迁”机会
python·flutter
liu****7 小时前
一.脚手架介绍以及部分工具使用
开发语言·数据结构·c++·手脚架开发
一只会奔跑的小橙子7 小时前
pytest安装对应的库的方法
python
资深web全栈开发7 小时前
深入理解 Google Wire:Go 语言的编译时依赖注入框架
开发语言·后端·golang
ohoy7 小时前
EasyPoi 数据脱敏
开发语言·python·excel