面向对象四大特征与SOLID原则详解
2026/8/12 9:39:14 网站建设 项目流程

一、什么是面向对象

面向对象编程是一种编程范式,它将现实世界的事物抽象为对象,通过对象之间的交互来完成程序功能。其核心思想是:万物皆对象

与面向过程(C语言)相比,OOP更符合人类的思维方式,让代码更易于理解、维护和扩展。

二、四大基本特征

1. 封装(Encapsulation)

将数据(属性)和操作数据的方法捆绑在一起,并隐藏内部实现细节,只对外暴露必要的接口。

作用

  • 保护数据安全,防止外部随意修改

  • 降低耦合度,内部变化不影响外部调用

python

class BankAccount: """银行账户类 - 封装示例""" def __init__(self, owner, balance): self.owner = owner self.__balance = balance # 私有属性(双下划线表示私有) self.__transaction_log = [] # 交易记录,外部不可见 # 对外提供的公开方法:存取款 def deposit(self, amount): """存款""" if amount <= 0: raise ValueError("存款金额必须大于0") self.__balance += amount self.__log_transaction(f"存款 +{amount}") def withdraw(self, amount): """取款 - 内部包含业务校验""" if amount <= 0: raise ValueError("取款金额必须大于0") if amount > self.__balance: raise ValueError("余额不足") self.__balance -= amount self.__log_transaction(f"取款 -{amount}") def get_balance(self): """通过方法获取余额(只读访问)""" return self.__balance def __log_transaction(self, msg): """私有方法:记录交易,外部无法调用""" self.__transaction_log.append(msg) def show_history(self): """展示交易记录""" for log in self.__transaction_log: print(log) # 使用示例 acc = BankAccount("张三", 1000) acc.deposit(500) acc.withdraw(200) print(acc.get_balance()) # 1300 # 以下操作会报错 # print(acc.__balance) # AttributeError: 私有属性不可访问 # acc.__log_transaction("xxx") # AttributeError: 私有方法不可调用

2. 继承(Inheritance)

子类可以继承父类的属性和方法,并能在此基础上扩展或重写。

作用

  • 代码复用,减少重复

  • 建立类之间的层次关系

  • 为多态奠定基础

python

class Animal: """父类(基类)""" def __init__(self, name, age): self.name = name self.age = age def eat(self): print(f"{self.name}正在吃东西") def sleep(self): print(f"{self.name}正在睡觉") def speak(self): """父类方法,子类会重写""" print("动物发出声音") class Dog(Animal): """子类:狗 - 继承Animal""" def __init__(self, name, age, breed): # 调用父类构造函数 super().__init__(name, age) self.breed = breed # 子类特有属性 # 重写父类方法 def speak(self): print(f"{self.name}汪汪叫") # 子类特有方法 def wag_tail(self): print(f"{self.name}摇尾巴") class Cat(Animal): """子类:猫""" def speak(self): print(f"{self.name}喵喵叫") def climb_tree(self): print(f"{self.name}爬上了树") # 使用示例 dog = Dog("旺财", 3, "金毛") dog.eat() # 继承自父类 dog.speak() # 重写后的方法 dog.wag_tail() # 子类特有 cat = Cat("咪咪", 2) cat.sleep() # 继承自父类 cat.speak() # 重写后的方法 cat.climb_tree() # 子类特有

3. 多态(Polymorphism)

同一个方法在不同对象上有不同的表现形式。简单说就是:相同的接口,不同的实现

作用

  • 提高代码的灵活性和可扩展性

  • 符合开闭原则(对扩展开放,对修改关闭)

python

class Shape: """形状基类""" def area(self): """计算面积 - 父类默认实现""" pass def perimeter(self): """计算周长""" pass class Circle(Shape): """圆形""" def __init__(self, radius): self.radius = radius def area(self): return 3.14159 * self.radius ** 2 def perimeter(self): return 2 * 3.14159 * self.radius class Rectangle(Shape): """矩形""" def __init__(self, width, height): self.width = width self.height = height def area(self): return self.width * self.height def perimeter(self): return 2 * (self.width + self.height) class Triangle(Shape): """三角形""" def __init__(self, a, b, c): self.a = a self.b = b self.c = c def area(self): # 海伦公式 s = (self.a + self.b + self.c) / 2 return (s * (s - self.a) * (s - self.b) * (s - self.c)) ** 0.5 def perimeter(self): return self.a + self.b + self.c # 多态的核心用法:同一个函数处理不同类型的对象 def print_shape_info(shape: Shape): """传入任何Shape子类都能正常工作""" print(f"面积: {shape.area():.2f}") print(f"周长: {shape.perimeter():.2f}") print("-" * 20) # 使用示例:同一个函数,不同表现 shapes = [ Circle(5), Rectangle(4, 6), Triangle(3, 4, 5) ] for shape in shapes: print_shape_info(shape) # 输出: # 面积: 78.54 # 周长: 31.42 # -------------------- # 面积: 24.00 # 周长: 20.00 # -------------------- # 面积: 6.00 # 周长: 12.00 # --------------------

4. 抽象(Abstraction)

只暴露必要的接口,隐藏复杂的实现细节。通常通过抽象类接口来实现。

作用

  • 定义规范,约束子类必须实现某些方法

  • 提高代码的可维护性和可读性

python

from abc import ABC, abstractmethod class Payment(ABC): """支付抽象类 - 定义支付规范""" @abstractmethod def pay(self, amount): """支付方法 - 子类必须实现""" pass @abstractmethod def refund(self, order_id): """退款方法 - 子类必须实现""" pass def log_transaction(self, msg): """普通方法:子类直接继承使用""" print(f"[日志] {msg}") class Alipay(Payment): """支付宝支付实现""" def __init__(self, account): self.account = account def pay(self, amount): # 复杂的支付宝API调用逻辑... self.log_transaction(f"支付宝账户{self.account}支付{amount}元") print(f"支付宝支付成功:{amount}元") def refund(self, order_id): self.log_transaction(f"支付宝退款订单{order_id}") print(f"支付宝退款成功:订单{order_id}") class WechatPay(Payment): """微信支付实现""" def __init__(self, openid): self.openid = openid def pay(self, amount): self.log_transaction(f"微信用户{self.openid}支付{amount}元") print(f"微信支付成功:{amount}元") def refund(self, order_id): self.log_transaction(f"微信退款订单{order_id}") print(f"微信退款成功:订单{order_id}") # 使用示例 def process_payment(payment: Payment, amount): """多态 + 抽象结合:处理任意支付方式""" payment.pay(amount) alipay = Alipay("zhangsan@alipay.com") wechat = WechatPay("wx_123456") process_payment(alipay, 100) process_payment(wechat, 200) # 以下会报错:抽象类不能直接实例化 # p = Payment() # TypeError: Can't instantiate abstract class Payment

三、五大设计原则(SOLID)

SOLID是面向对象设计的五个基本原则,是写出高质量OOP代码的基石。

原则全称含义
S单一职责原则一个类只做一件事
O开闭原则对扩展开放,对修改关闭
L里氏替换原则子类必须能替换父类
I接口隔离原则不强迫实现不需要的方法
D依赖倒置原则依赖抽象不依赖具体

单一职责原则示例

python

# ❌ 反面案例:一个类承担了太多职责 class UserManager: def create_user(self, name, email): pass def save_to_db(self, user): pass def send_email(self, user, content): pass def generate_report(self, users): pass # ✅ 正面案例:职责分离 class User: """只负责用户数据本身""" def __init__(self, name, email): self.name = name self.email = email class UserRepository: """只负责数据库操作""" def save(self, user): pass def find_by_id(self, id): pass class EmailService: """只负责邮件发送""" def send(self, user, content): pass class ReportGenerator: """只负责报表生成""" def generate(self, users): pass

四、进阶特性

1. 类方法、静态方法、实例方法

python

class Student: school = "北京大学" # 类属性(所有实例共享) def __init__(self, name, score): self.name = name # 实例属性 self.score = score # 实例方法:需要self,访问实例属性 def get_grade(self): if self.score >= 90: return "A" elif self.score >= 80: return "B" else: return "C" # 类方法:需要cls,操作类属性 @classmethod def change_school(cls, new_school): cls.school = new_school # 类方法:作为工厂方法(替代构造函数) @classmethod def create_from_dict(cls, data): return cls(data['name'], data['score']) # 静态方法:不需要self或cls,纯工具函数 @staticmethod def is_valid_score(score): return 0 <= score <= 100 # 使用示例 s1 = Student("小明", 95) s2 = Student("小红", 78) # 实例方法 print(s1.get_grade()) # A # 类方法 print(Student.school) # 北京大学 Student.change_school("清华大学") print(Student.school) # 清华大学 # 工厂方法 data = {"name": "小刚", "score": 85} s3 = Student.create_from_dict(data) print(s3.name) # 小刚 # 静态方法 print(Student.is_valid_score(105)) # False

2. 属性装饰器(@property)

将方法伪装成属性,实现更优雅的getter/setter。

python

class Temperature: """温度类 - 使用@property实现属性访问控制""" def __init__(self, celsius): self._celsius = celsius # 私有属性 @property def celsius(self): """获取摄氏温度""" return self._celsius @celsius.setter def celsius(self, value): """设置摄氏温度(带校验)""" if value < -273.15: raise ValueError("温度不能低于绝对零度") self._celsius = value @property def fahrenheit(self): """计算属性:华氏温度(只读)""" return self._celsius * 9 / 5 + 32 @fahrenheit.setter def fahrenheit(self, value): """通过华氏温度设置摄氏温度""" self._celsius = (value - 32) * 5 / 9 # 使用示例 temp = Temperature(25) print(temp.celsius) # 25 print(temp.fahrenheit) # 77.0 temp.celsius = 30 # 通过setter修改 print(temp.fahrenheit) # 86.0 temp.fahrenheit = 100 # 通过华氏修改 print(temp.celsius) # 37.78 # 带校验的赋值 # temp.celsius = -300 # ValueError: 温度不能低于绝对零度

3. 多重继承与MRO(方法解析顺序)

Python支持多重继承,但需注意菱形继承问题。

python

class A: def show(self): print("A") class B(A): def show(self): print("B") class C(A): def show(self): print("C") class D(B, C): pass # MRO: Method Resolution Order d = D() d.show() # B (按MRO顺序查找) print(D.__mro__) # (<class '__main__.D'>, <class '__main__.B'>, # <class '__main__.C'>, <class '__main__.A'>, <class 'object'>)

4. 魔术方法(Magic Methods / Dunder Methods)

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 int((self.x ** 2 + self.y ** 2) ** 0.5) # 可迭代 def __iter__(self): yield self.x yield self.y # 索引访问 def __getitem__(self, index): if index == 0: return self.x elif index == 1: return self.y raise IndexError("索引超出范围") # 使用示例 v1 = Vector(3, 4) v2 = Vector(1, 2) print(v1) # Vector(3, 4) -> __str__ print(v1 + v2) # Vector(4, 6) -> __add__ print(v1 - v2) # Vector(2, 2) -> __sub__ print(v1 * 2) # Vector(6, 8) -> __mul__ print(v1 == Vector(3, 4)) # True -> __eq__ print(len(v1)) # 5 -> __len__ for coord in v1: # -> __iter__ print(coord) # 3, 4 print(v1[0]) # 3 -> __getitem__

五、总结对比

特性作用关键语法
封装隐藏实现,保护数据__private@property
继承代码复用,建立层次class Sub(Parent)super()
多态统一接口,不同实现方法重写、isinstance()
抽象定义规范,约束行为ABC@abstractmethod
类方法操作类级数据@classmethod
静态方法工具函数,与类无关@staticmethod
魔术方法让对象像原生类型一样操作__add____str__

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询