Rust 学习笔记 23:面向对象特性 (Object Oriented Features)

Rust 学习笔记 23:面向对象特性 (Object Oriented Features) “The problem with object-oriented languages is they’ve got all this implicit environment that they carry around with them. You wanted a banana but you got a gorilla holding the banana and the entire jungle.” – Joe Armstrong Rust 是面向对象语言吗?这取决于你对 OOP 的定义。 如果定义是"封装、继承、多态",那么 Rust: 封装:有。struct 和 impl,以及 pub 关键字。 继承:没有。Rust 没有任何继承机制(Struct 不能继承 Struct)。 多态:有。通过泛型(静态多态)和 Trait Objects(动态多态)。 1. Trait Objects (动态分发) 我们在泛型那一章学过用 Trait Bound 实现多态: 1fn draw<T: Draw>(item: T) { item.draw(); } 这种是静态分发 (Static Dispatch)。编译器会为每种具体的 T 生成一份代码。优点是快,缺点是 Vec<T> 里的所有元素必须是同一种类型。 ...

2026-01-20 · 2 min · 215 words · 老墨

Python教程42:综合项目-图书管理系统

Python教程42:综合项目-图书管理系统 “纸上得来终觉浅,绝知此事要躬行。” 经过第四部分12课的学习,我们掌握了OOP的核心概念。今天通过一个完整的图书管理系统,综合运用所学知识。 1. 项目需求 功能需求 基本功能: 图书管理:添加、删除、搜索、借阅、归还 用户管理:注册、借阅记录 分类管理:按类别组织图书 进阶功能: 数据持久化(JSON) 借阅期限和逾期管理 统计报表 技术要求 使用类和对象 继承和多态 抽象基类 属性管理(@property) 异常处理 文件操作 2. 系统设计 类设计 Library System ├── Book(图书基类) │ ├── PhysicalBook(实体书) │ └── EBook(电子书) ├── User(用户类) ├── Library(图书馆类) ├── BorrowRecord(借阅记录) └── Storage(存储类) 3. 核心实现 Book基类 1from abc import ABC, abstractmethod 2from datetime import datetime 3 4class Book(ABC): 5 """图书抽象基类""" 6 7 def __init__(self, isbn, title, author, category): 8 self.isbn = isbn 9 self.title = title 10 self.author = author 11 self.category = category 12 self.is_borrowed = False 13 14 @abstractmethod 15 def get_type(self): 16 """获取图书类型""" 17 pass 18 19 def to_dict(self): 20 """序列化""" 21 return { 22 'isbn': self.isbn, 23 'title': self.title, 24 'author': self.author, 25 'category': self.category, 26 'is_borrowed': self.is_borrowed, 27 'type': self.get_type() 28 } 29 30 def __str__(self): 31 status = "已借出" if self.is_borrowed else "可借阅" 32 return f"{self.title} by {self.author} ({status})" 33 34class PhysicalBook(Book): 35 """实体书""" 36 def __init__(self, isbn, title, author, category, location): 37 super().__init__(isbn, title, author, category) 38 self.location = location # 书架位置 39 40 def get_type(self): 41 return "physical" 42 43 def to_dict(self): 44 data = super().to_dict() 45 data['location'] = self.location 46 return data 47 48class EBook(Book): 49 """电子书""" 50 def __init__(self, isbn, title, author, category, file_size): 51 super().__init__(isbn, title, author, category) 52 self.file_size = file_size # 文件大小(MB) 53 54 def get_type(self): 55 return "ebook" 56 57 def to_dict(self): 58 data = super().to_dict() 59 data['file_size'] = self.file_size 60 return data User类 1class User: 2 """用户类""" 3 4 def __init__(self, user_id, name, email): 5 self.user_id = user_id 6 self.name = name 7 self.email = email 8 self.borrowed_books = [] # ISBN列表 9 10 def can_borrow(self, max_books=5): 11 """检查是否可以借阅""" 12 return len(self.borrowed_books) < max_books 13 14 def borrow_book(self, isbn): 15 """借阅图书""" 16 if isbn not in self.borrowed_books: 17 self.borrowed_books.append(isbn) 18 19 def return_book(self, isbn): 20 """归还图书""" 21 if isbn in self.borrowed_books: 22 self.borrowed_books.remove(isbn) 23 24 def to_dict(self): 25 return { 26 'user_id': self.user_id, 27 'name': self.name, 28 'email': self.email, 29 'borrowed_books': self.borrowed_books 30 } 31 32 def __str__(self): 33 return f"User({self.name}, 已借{len(self.borrowed_books)}本)" BorrowRecord类 1class BorrowRecord: 2 """借阅记录""" 3 4 def __init__(self, user_id, isbn, borrow_date=None): 5 self.user_id = user_id 6 self.isbn = isbn 7 self.borrow_date = borrow_date or datetime.now() 8 self.return_date = None 9 self.due_date = self.borrow_date + timedelta(days=30) 10 11 @property 12 def is_overdue(self): 13 """是否逾期""" 14 if self.return_date: 15 return False 16 return datetime.now() > self.due_date 17 18 def mark_returned(self): 19 """标记为已归还""" 20 self.return_date = datetime.now() 21 22 def to_dict(self): 23 return { 24 'user_id': self.user_id, 25 'isbn': self.isbn, 26 'borrow_date': self.borrow_date.isoformat(), 27 'due_date': self.due_date.isoformat(), 28 'return_date': self.return_date.isoformat() if self.return_date else None 29 } Library类 1class Library: 2 """图书馆类""" 3 4 def __init__(self, name): 5 self.name = name 6 self.books = {} # ISBN -> Book 7 self.users = {} # user_id -> User 8 self.records = [] # BorrowRecord列表 9 10 def add_book(self, book): 11 """添加图书""" 12 if book.isbn in self.books: 13 raise ValueError(f"图书{book.isbn}已存在") 14 self.books[book.isbn] = book 15 16 def remove_book(self, isbn): 17 """删除图书""" 18 if isbn not in self.books: 19 raise ValueError(f"图书{isbn}不存在") 20 if self.books[isbn].is_borrowed: 21 raise ValueError("图书已借出,无法删除") 22 del self.books[isbn] 23 24 def register_user(self, user): 25 """注册用户""" 26 if user.user_id in self.users: 27 raise ValueError(f"用户{user.user_id}已存在") 28 self.users[user.user_id] = user 29 30 def borrow_book(self, user_id, isbn): 31 """借阅图书""" 32 # 验证 33 if user_id not in self.users: 34 raise ValueError("用户不存在") 35 if isbn not in self.books: 36 raise ValueError("图书不存在") 37 38 user = self.users[user_id] 39 book = self.books[isbn] 40 41 if book.is_borrowed: 42 raise ValueError("图书已被借出") 43 if not user.can_borrow(): 44 raise ValueError("借阅数量已达上限") 45 46 # 借阅 47 book.is_borrowed = True 48 user.borrow_book(isbn) 49 record = BorrowRecord(user_id, isbn) 50 self.records.append(record) 51 52 return f"{user.name}成功借阅《{book.title}》" 53 54 def return_book(self, user_id, isbn): 55 """归还图书""" 56 if user_id not in self.users: 57 raise ValueError("用户不存在") 58 if isbn not in self.books: 59 raise ValueError("图书不存在") 60 61 user = self.users[user_id] 62 book = self.books[isbn] 63 64 if not book.is_borrowed: 65 raise ValueError("图书未被借出") 66 67 # 归还 68 book.is_borrowed = False 69 user.return_book(isbn) 70 71 # 更新记录 72 for record in reversed(self.records): 73 if (record.user_id == user_id and 74 record.isbn == isbn and 75 not record.return_date): 76 record.mark_returned() 77 break 78 79 return f"{user.name}成功归还《{book.title}》" 80 81 def search_books(self, keyword): 82 """搜索图书""" 83 results = [] 84 keyword = keyword.lower() 85 for book in self.books.values(): 86 if (keyword in book.title.lower() or 87 keyword in book.author.lower() or 88 keyword in book.category.lower()): 89 results.append(book) 90 return results 91 92 def get_statistics(self): 93 """获取统计信息""" 94 total_books = len(self.books) 95 borrowed = sum(1 for book in self.books.values() if book.is_borrowed) 96 overdue = sum(1 for record in self.records if record.is_overdue) 97 98 return { 99 'total_books': total_books, 100 'available': total_books - borrowed, 101 'borrowed': borrowed, 102 'total_users': len(self.users), 103 'overdue_records': overdue 104 } 4. 使用示例 1# 创建图书馆 2library = Library("市图书馆") 3 4# 添加图书 5book1 = PhysicalBook("978-1", "Python编程", "作者A", "编程", "A-101") 6book2 = EBook("978-2", "数据结构", "作者B", "编程", 15.5) 7library.add_book(book1) 8library.add_book(book2) 9 10# 注册用户 11user = User("U001", "张三", "zhang@example.com") 12library.register_user(user) 13 14# 借阅流程 15print(library.borrow_book("U001", "978-1")) 16print(library.borrow_book("U001", "978-2")) 17 18# 搜索 19results = library.search_books("Python") 20for book in results: 21 print(book) 22 23# 统计 24stats = library.get_statistics() 25print(f"总藏书:{stats['total_books']}") 26print(f"可借阅:{stats['available']}") 27print(f"已借出:{stats['borrowed']}") 28 29# 归还 30print(library.return_book("U001", "978-1")) 5. 知识点回顾 这个项目运用了: ...

2026-01-08 · 5 min · 874 words · 老墨

Python教程40:常用设计模式

Python教程40:常用设计模式 “不要重复造轮子。” 设计模式是解决常见问题的可复用方案。今天我们学习Python中常用的设计模式,提升代码设计能力。 1. 创建型模式 单例模式(Singleton) 确保类只有一个实例: 1class Singleton: 2 _instance = None 3 4 def __new__(cls): 5 if cls._instance is None: 6 cls._instance = super().__new__(cls) 7 return cls._instance 8 9# 或使用装饰器 10def singleton(cls): 11 instances = {} 12 def get_instance(*args, **kwargs): 13 if cls not in instances: 14 instances[cls] = cls(*args, **kwargs) 15 return instances[cls] 16 return get_instance 17 18@singleton 19class Database: 20 def __init__(self, url): 21 self.url = url 工厂模式(Factory) 根据条件创建不同对象: 1class ShapeFactory: 2 @staticmethod 3 def create_shape(shape_type): 4 if shape_type == "circle": 5 return Circle() 6 elif shape_type == "rectangle": 7 return Rectangle() 8 else: 9 raise ValueError(f"未知形状:{shape_type}") 10 11# 使用 12shape = ShapeFactory.create_shape("circle") 建造者模式(Builder) 分步骤构建复杂对象: 1class QueryBuilder: 2 def __init__(self): 3 self._select = [] 4 self._from = None 5 self._where = [] 6 7 def select(self, *fields): 8 self._select.extend(fields) 9 return self 10 11 def from_table(self, table): 12 self._from = table 13 return self 14 15 def where(self, condition): 16 self._where.append(condition) 17 return self 18 19 def build(self): 20 query = f"SELECT {', '.join(self._select)}" 21 query += f" FROM {self._from}" 22 if self._where: 23 query += f" WHERE {' AND '.join(self._where)}" 24 return query 25 26# 使用(链式调用) 27sql = (QueryBuilder() 28 .select("name", "age") 29 .from_table("users") 30 .where("age > 18") 31 .build()) 2. 结构型模式 适配器模式(Adapter) 使不兼容的接口协同工作: ...

2025-12-11 · 4 min · 658 words · 老墨

Python教程35:类方法与静态方法

Python教程35:类方法与静态方法 “工欲善其事,必先利其器。” Python提供了三种方法类型:实例方法、类方法、静态方法。今天我们学习类方法(@classmethod)和静态方法(@staticmethod),理解它们的区别和使用场景。 1. 三种方法类型对比 实例方法(Instance Method) 我们最常用的方法: 1class MyClass: 2 def instance_method(self): 3 """ 4 实例方法 5 - 第一个参数是self(实例本身) 6 - 可以访问实例属性和类属性 7 - 通过实例调用 8 """ 9 print(f"Called instance_method of {self}") 10 return "instance method" 11 12obj = MyClass() 13obj.instance_method() # 正常调用 类方法(Class Method) 使用@classmethod装饰器: 1class MyClass: 2 @classmethod 3 def class_method(cls): 4 """ 5 类方法 6 - 第一个参数是cls(类本身) 7 - 可以访问类属性,不能访问实例属性 8 - 通过类或实例调用 9 """ 10 print(f"Called class_method of {cls}") 11 return "class method" 12 13# 通过类调用 14MyClass.class_method() 15 16# 通过实例调用也可以 17obj = MyClass() 18obj.class_method() 静态方法(Static Method) 使用@staticmethod装饰器: ...

2025-08-26 · 6 min · 1150 words · 老墨

Python教程34:魔术方法(Magic Methods)

Python教程34:魔术方法(Magic Methods) “命名即魔法。” Python的魔术方法(也叫特殊方法、双下划线方法)是Python面向对象的核心特性。它们让你的类能够像内置类型一样工作,实现运算符重载、容器协议等高级功能。 1. 什么是魔术方法 魔术方法(Magic Methods): 双下划线开头和结尾的方法:__method__ Python自动调用,不需要显式调用 让类支持Python的特殊语法 也叫"dunder methods"(double underscore) 为什么需要魔术方法: 运算符重载:让对象支持+、-、*等运算 容器协议:让对象可迭代、可索引 上下文管理:支持with语句 对象表示:自定义打印输出 属性访问:控制属性读写 简单示例 1class Point: 2 """二维点""" 3 def __init__(self, x, y): 4 """初始化(魔术方法)""" 5 self.x = x 6 self.y = y 7 8 def __str__(self): 9 """字符串表示(魔术方法)""" 10 return f"Point({self.x}, {self.y})" 11 12 def __add__(self, other): 13 """加法运算符(魔术方法)""" 14 return Point(self.x + other.x, self.y + other.y) 15 16# 使用 17p1 = Point(1, 2) 18p2 = Point(3, 4) 19 20print(p1) # 调用__str__: Point(1, 2) 21p3 = p1 + p2 # 调用__add__ 22print(p3) # Point(4, 6) 2. 对象创建和销毁 new:创建实例 1class Singleton: 2 """ 3 单例模式 4 - __new__在__init__之前调用 5 - __new__负责创建实例 6 - __new__是类方法 7 """ 8 _instance = None 9 10 def __new__(cls): 11 """ 12 创建实例 13 - cls是类本身 14 - 必须返回实例 15 """ 16 if cls._instance is None: 17 print("Creating singleton instance") 18 cls._instance = super().__new__(cls) 19 return cls._instance 20 21 def __init__(self): 22 """初始化实例""" 23 print("Initializing instance") 24 25# 使用 26s1 = Singleton() # Creating singleton instance, Initializing instance 27s2 = Singleton() # Initializing instance (不创建新实例) 28print(s1 is s2) # True(同一个实例) init:初始化 我们已经很熟悉了: ...

2025-07-28 · 8 min · 1524 words · 老墨

Python教程33:多态

Python教程33:多态 “一个接口,多种实现。” 多态是面向对象编程三大特性(封装、继承、多态)的最后一个。今天我们学习Python的多态特性,理解如何让代码更灵活、更易扩展。 1. 什么是多态 多态(Polymorphism): Poly(多个)+ morph(形态) 同一个接口,不同的实现 不同对象对同一消息的不同响应 为什么需要多态: 灵活性:通过父类引用调用子类方法 可扩展:添加新类无需修改现有代码 统一接口:不同对象用相同方式操作 解耦合:调用者不关心对象类型 简单示例 1class Animal: 2 """动物基类""" 3 def speak(self): 4 pass 5 6class Dog(Animal): 7 def speak(self): 8 return "Woof!" 9 10class Cat(Animal): 11 def speak(self): 12 return "Meow!" 13 14class Cow(Animal): 15 def speak(self): 16 return "Moo!" 17 18# 多态:相同的方法调用,不同的行为 19def animal_sound(animal): 20 """ 21 统一的接口 22 - 参数是Animal类型 23 - 不关心具体是什么动物 24 - 调用speak()得到不同的结果 25 """ 26 print(animal.speak()) 27 28# 使用 29animals = [Dog(), Cat(), Cow()] 30for animal in animals: 31 animal_sound(animal) 32# 输出: 33# Woof! 34# Meow! 35# Moo! 多态的好处: ...

2025-06-24 · 5 min · 987 words · 老墨

Python教程32:继承

Python教程32:继承 “站在巨人的肩膀上。” 继承是面向对象编程的三大特性之一(封装、继承、多态),它让我们可以基于已有类创建新类,实现代码复用。今天我们深入学习Python的继承机制。 1. 什么是继承 问题场景 假设要创建多个类: 1# 没有继承:代码重复 2class Dog: 3 def __init__(self, name, age): 4 self.name = name 5 self.age = age 6 7 def eat(self): 8 return f"{self.name} is eating" 9 10class Cat: 11 def __init__(self, name, age): 12 self.name = name 13 self.age = age 14 15 def eat(self): 16 return f"{self.name} is eating" 17 18 def meow(self): 19 return "Meow!" 20 21# 重复的代码... 继承(Inheritance): 子类继承父类的属性和方法 子类可以添加新的属性和方法 子类可以重写父类的方法 实现代码复用,减少重复 为什么需要继承: 代码复用:共享功能写一次 逻辑清晰:体现is-a关系(狗是动物) 易于维护:修改父类,所有子类受益 扩展性强:基于现有代码扩展新功能 继承的基本语法 1class ParentClass: 2 """父类(基类、超类)""" 3 pass 4 5class ChildClass(ParentClass): 6 """子类(派生类)""" 7 pass 2. 基本继承 简单示例 1class Animal: 2 """动物类(父类)""" 3 4 def __init__(self, name, age): 5 """初始化动物""" 6 self.name = name 7 self.age = age 8 9 def eat(self): 10 """吃东西(所有动物都会吃)""" 11 return f"{self.name} is eating" 12 13 def sleep(self): 14 """睡觉""" 15 return f"{self.name} is sleeping" 16 17class Dog(Animal): 18 """狗类(子类)- 继承Animal""" 19 20 def bark(self): 21 """狗叫(狗特有的方法)""" 22 return f"{self.name} says: Woof!" 23 24class Cat(Animal): 25 """猫类(子类)- 继承Animal""" 26 27 def meow(self): 28 """猫叫(猫特有的方法)""" 29 return f"{self.name} says: Meow!" 30 31# 使用 32dog = Dog("Buddy", 3) 33print(dog.eat()) # 继承自Animal:Buddy is eating 34print(dog.bark()) # Dog自己的方法:Buddy says: Woof! 35 36cat = Cat("Whiskers", 2) 37print(cat.eat()) # 继承自Animal:Whiskers is eating 38print(cat.meow()) # Cat自己的方法:Whiskers says: Meow! 继承的特点: ...

2025-05-10 · 6 min · 1135 words · 老墨

Python教程31:类与对象基础

Python教程31:类与对象基础 “万物皆对象。” 从今天开始,我们进入Python编程的新境界——面向对象编程(OOP)。这是一种组织代码的强大范式,让程序更贴近真实世界的思维方式。 1. 什么是面向对象编程 编程范式的演进 面向过程编程(Procedural Programming): 以函数为中心 数据和操作分离 适合简单问题 1# 面向过程:管理学生信息 2students = [ 3 {"name": "Alice", "age": 20, "grade": 85}, 4 {"name": "Bob", "age": 21, "grade": 90} 5] 6 7def calculate_average(students): 8 """计算平均成绩""" 9 total = sum(s["grade"] for s in students) 10 return total / len(students) 11 12# 数据和操作分离 面向对象编程(Object-Oriented Programming, OOP): 以对象为中心 数据和操作封装在一起 更贴近真实世界建模 1# 面向对象:学生类 2class Student: 3 """学生类:数据和行为封装在一起""" 4 def __init__(self, name, age, grade): 5 self.name = name 6 self.age = age 7 self.grade = grade 8 9 def get_info(self): 10 """学生的行为""" 11 return f"{self.name}, {self.age}岁, 成绩{self.grade}" 12 13# 创建对象 14alice = Student("Alice", 20, 85) 15bob = Student("Bob", 21, 90) OOP的核心概念 类(Class): ...

2025-04-17 · 5 min · 1004 words · 老墨

Rust 学习笔记 08:结构体 (Structs)

Rust 学习笔记 08:结构体 (Structs) “Structure is the maker of light.” – Louis Kahn 在 Go 中,我们用 struct 来组织数据,用 func (s *Struct) Method() 来定义方法。 在 Rust 中,这种感觉非常相似,但细节决定成败。 1. 定义与实例化 定义一个 User 结构体: 1struct User { 2 active: bool, 3 username: String, 4 email: String, 5 sign_in_count: u64, 6} 这和 Go 几乎一模一样(除了字段名为 snake_case,Go 推荐 CamelCase)。 实例化: 1let user1 = User { 2 email: String::from("someone@example.com"), 3 username: String::from("someusername123"), 4 active: true, 5 sign_in_count: 1, 6}; 区别点:如果想修改 user1 的字段,必须把 user1 声明为 mut。Rust 不允许仅把某个字段标记为可变,可变性是针对整个实例的。 ...

2024-10-15 · 2 min · 342 words · 老墨