13-面向对象

Python面向对象编程全面指南

一、面向对象编程概述

1.1 面向对象的基本概念

1.1.1 为什么需要面向对象

在程序开发中,我们需要一种有效的方式来组织和管理数据。面向对象编程(OOP)提供了一种更加结构化和可维护的代码组织方式。

传统变量方式的局限性

# 混乱的数据组织方式
student_1 = "我叫周杰轮,今年31岁,男的,来自中国台湾省"
student_2 = "我叫林军杰,今年33岁,男的,来自中国山东省"

# 问题:数据分散,难以统一管理和操作

1.1.2 面向对象的优势

面向对象编程通过对象来组织数据,类似于生活中的表格登记:

1.2 面向对象三大特性

  • 封装:将数据和行为包装在类中
  • 继承:实现代码复用和扩展
  • 多态:同一操作作用于不同对象产生不同行为

二、类与对象基础

2.1 类的定义与使用

2.1.1 类的基本语法

class 类名称:
    # 类的属性(成员变量)
    属性1 = None
    属性2 = None
    
    # 类的行为(成员方法)
    def 方法名(self, 参数列表):
        方法体

2.1.2 实际示例

class Student:
    # 类的属性
    name = None      # 学生姓名
    age = None       # 学生年龄
    gender = None    # 学生性别
    address = None   # 学生地址
    
    # 类的行为
    def say_hi(self):
        print(f"大家好,我是{self.name},今年{self.age}岁")
    
    def study(self, course):
        print(f"{self.name}正在学习{course}课程")

2.1.3 创建和使用对象

# 创建对象(生产表格)
student1 = Student()
student2 = Student()

# 对象属性赋值(填写表格)
student1.name = "周杰轮"
student1.age = 31
student1.gender = "男"
student1.address = "台湾省"

student2.name = "林军杰" 
student2.age = 33
student2.gender = "男"
student2.address = "山东省"

# 使用对象方法
student1.say_hi()  # 输出:大家好,我是周杰轮,今年31岁
student2.study("Python")  # 输出:林军杰正在学习Python课程

2.2 self关键字详解

2.2.1 self的作用

self表示类对象自身,用于在方法内部访问类的属性和其他方法。

class Student:
    name = None
    age = None
    
    def introduce(self):
        # 使用self访问对象的属性
        print(f"姓名:{self.name},年龄:{self.age}")
    
    def set_info(self, name, age):
        # 使用self设置对象的属性
        self.name = name
        self.age = age
        self.introduce()  # 调用其他方法也需要self

2.2.2 方法调用机制

student = Student()
student.set_info("王小明", 20)
# 等价于:Student.set_info(student, "王小明", 20)
# Python自动将student作为第一个参数self传入

三、构造方法

3.1 构造方法的概念

3.1.1 为什么需要构造方法

传统的属性赋值方式繁琐:

student = Student()
student.name = "张三"
student.age = 20
student.gender = "男"
# 需要多行代码完成初始化

使用构造方法可以简化初始化过程。

3.1.2 构造方法语法

class Student:
    def __init__(self, name, age, gender):
        """构造方法,在创建对象时自动执行"""
        self.name = name
        self.age = age
        self.gender = gender
        print("学生对象创建完成!")
    
    def introduce(self):
        print(f"我叫{self.name},今年{self.age}岁")

# 使用构造方法初始化
student = Student("李四", 22, "女")
student.introduce()  # 输出:我叫李四,今年22岁

3.2 构造方法实践

3.2.1 学生信息录入系统

class Student:
    def __init__(self, name, age, address):
        """构造方法初始化学生信息"""
        self.name = name
        self.age = age
        self.address = address
    
    def display_info(self):
        """显示学生信息"""
        print(f"学生信息:姓名:{self.name}, 年龄:{self.age}, 地址:{self.address}")

# 批量录入学生信息
students = []
for i in range(3):
    print(f"录入第{i+1}个学生信息:")
    name = input("姓名:")
    age = int(input("年龄:"))
    address = input("地址:")
    
    student = Student(name, age, address)
    students.append(student)
    student.display_info()

四、类的内置方法

4.1 常用魔术方法

4.1.1 __str__ 方法

控制对象转换为字符串的表现形式:

class Student:
    def __init__(self, name, age):
        self.name = name
        self.age = age
    
    def __str__(self):
        """定义对象字符串表示"""
        return f"Student对象:name={self.name}, age={self.age}"

student = Student("周杰轮", 31)
print(student)  # 输出:Student对象:name=周杰轮, age=31
print(str(student))  # 输出:Student对象:name=周杰轮, age=31

4.1.2 __lt__ 方法

实现对象的小于比较:

class Student:
    def __init__(self, name, age):
        self.name = name
        self.age = age
    
    def __lt__(self, other):
        """定义小于比较规则"""
        return self.age < other.age

stu1 = Student("张三", 20)
stu2 = Student("李四", 22)
print(stu1 < stu2)  # 输出:True
print(stu1 > stu2)  # 输出:False(自动支持)

4.1.3 __le__ 方法

实现对象的小于等于比较:

class Student:
    def __init__(self, name, score):
        self.name = name
        self.score = score
    
    def __le__(self, other):
        """定义小于等于比较规则"""
        return self.score <= other.score

stu1 = Student("张三", 85)
stu2 = Student("李四", 85)
print(stu1 <= stu2)  # 输出:True
print(stu1 >= stu2)  # 输出:True(自动支持)

4.1.4 __eq__ 方法

实现对象的相等比较:

class Student:
    def __init__(self, name, student_id):
        self.name = name
        self.student_id = student_id
    
    def __eq__(self, other):
        """定义相等比较规则"""
        return self.student_id == other.student_id

stu1 = Student("张三", "2023001")
stu2 = Student("李四", "2023001")
stu3 = Student("王五", "2023002")
print(stu1 == stu2)  # 输出:True
print(stu1 == stu3)  # 输出:False

4.2 魔术方法综合应用

class Product:
    """商品类"""
    
    def __init__(self, name, price, quantity):
        self.name = name
        self.price = price
        self.quantity = quantity
    
    def __str__(self):
        return f"商品:{self.name},价格:{self.price}元,库存:{self.quantity}"
    
    def __lt__(self, other):
        return self.price < other.price
    
    def __eq__(self, other):
        return self.name == other.name and self.price == other.price

# 使用示例
p1 = Product("手机", 2999, 10)
p2 = Product("平板", 3999, 5)
p3 = Product("手机", 2999, 8)

print(p1)        # 输出商品信息
print(p1 < p2)   # 输出:True
print(p1 == p3)  # 输出:True

五、封装

5.1 封装的概念

5.1.1 什么是封装

封装是将现实世界事物的属性和行为封装到类中,描述为成员变量和成员方法。

5.1.2 私有成员

私有成员是对外部隐藏的属性和方法,只能在类内部访问:

class Phone:
    # 公开成员变量
    IMEI = None        # 序列号
    producer = None     # 厂商
    
    # 私有成员变量
    __current_voltage = None  # 当前电压
    
    def call_by_5g(self):
        """公开方法"""
        if self.__check_5g():
            print("5G通话已开启")
        else:
            print("5G通话关闭,使用4G通话")
    
    def __check_5g(self):
        """私有方法:检查5G状态"""
        if self.__current_voltage >= 1:
            return True
        else:
            return False

5.2 封装实践

5.2.1 手机类设计

class Phone:
    def __init__(self):
        # 私有成员变量
        self.__is_5g_enable = True  # 5G状态
    
    def __check_5g(self):
        """私有方法:检查5G状态"""
        if self.__is_5g_enable:
            print("5G开启")
        else:
            print("5G关闭,使用4G网络")
    
    def call_by_5g(self):
        """公开方法:5G通话"""
        self.__check_5g()
        print("正在通话中")

# 使用
phone = Phone()
phone.call_by_5g()
# 输出:
# 5G开启
# 正在通话中

# 以下操作会报错
# phone.__is_5g_enable = False  # 错误:无法直接访问私有变量
# phone.__check_5g()            # 错误:无法直接调用私有方法

5.2.2 封装的优点

  1. 数据保护:防止外部直接修改内部数据
  2. 接口统一:提供统一的访问接口
  3. 实现隐藏:隐藏内部实现细节,降低耦合度

六、继承

6.1 继承的基本概念

6.1.1 为什么需要继承

继承可以实现代码复用,避免重复编写相似的代码。

6.1.2 单继承

class Phone:
    """父类:手机基类"""
    IMEI = None        # 序列号
    producer = None     # 厂商
    
    def call_by_4g(self):
        print("4G通话")

class Phone2022(Phone):
    """子类:2022年手机"""
    face_id = True      # 面部识别
    
    def call_by_5g(self):
        print("2022最新5G通话")

# 使用
phone2022 = Phone2022()
phone2022.call_by_4g()  # 继承自父类
phone2022.call_by_5g()  # 自己的功能

6.2 多继承

6.2.1 多继承语法

class NFCReader:
    """NFC读取器"""
    nfc_type = "第五代"
    producer = "HM"
    
    def read_card(self):
        print("读取NFC卡")

class RemoteControl:
    """遥控器"""
    rc_type = "红外遥控"
    
    def control(self):
        print("红外遥控开启")

class MyPhone(Phone, NFCReader, RemoteControl):
    """多继承:我的手机"""
    pass

# 使用
my_phone = MyPhone()
my_phone.call_by_4g()  # 来自Phone
my_phone.read_card()   # 来自NFCReader  
my_phone.control()     # 来自RemoteControl

6.2.2 多继承注意事项

class A:
    value = "A"
    
class B:
    value = "B"

class C(A, B):  # 继承顺序:A → B
    pass

class D(B, A):  # 继承顺序:B → A  
    pass

print(C().value)  # 输出:"A"(优先使用A的value)
print(D().value)  # 输出:"B"(优先使用B的value)

6.3 方法重写

6.3.1 重写父类方法

class Animal:
    def speak(self):
        print("动物发出声音")

class Dog(Animal):
    def speak(self):
        print("汪汪汪")  # 重写父类方法

class Cat(Animal):
    def speak(self):
        print("喵喵喵")  # 重写父类方法

# 使用
dog = Dog()
cat = Cat()
dog.speak()  # 输出:汪汪汪
cat.speak()  # 输出:喵喵喵

6.3.2 调用父类方法

class Animal:
    def __init__(self, name):
        self.name = name

class Dog(Animal):
    def __init__(self, name, breed):
        # 方式1:使用父类名调用
        Animal.__init__(self, name)
        # 方式2:使用super()调用(推荐)
        super().__init__(name)
        self.breed = breed

dog = Dog("旺财", "金毛")

七、类型注解

7.1 变量类型注解

7.1.1 基础类型注解

# 基础数据类型注解
var_1: int = 10
var_2: float = 3.14
var_3: bool = True
var_4: str = "hello"

# 类对象类型注解
class Student:
    pass

stu: Student = Student()

7.1.2 容器类型注解

from typing import List, Dict, Tuple, Set

# 基础容器注解
my_list: List[int] = [1, 2, 3]
my_dict: Dict[str, int] = {"age": 20, "score": 95}
my_tuple: Tuple[str, int, bool] = ("张三", 20, True)
my_set: Set[int] = {1, 2, 3}

# 注释中的类型注解
data = get_data()  # type: Dict[str, int]

7.2 函数类型注解

7.2.1 函数参数和返回值注解

def add(x: int, y: int) -> int:
    """加法函数"""
    return x + y

def process_students(students: List[Student]) -> Dict[str, int]:
    """处理学生列表,返回姓名-年龄字典"""
    return {s.name: s.age for s in students}

# 使用
result: int = add(5, 3)
print(result)  # 输出:8

7.2.2 Union类型注解

from typing import Union

def process_data(data: Union[int, str, List]) -> Union[int, str]:
    """处理多种类型数据"""
    if isinstance(data, int):
        return data * 2
    elif isinstance(data, str):
        return data.upper()
    else:
        return str(len(data))

# 容器中的Union类型
mixed_list: List[Union[int, str]] = [1, "hello", 2, "world"]

八、多态

8.1 多态的概念

8.1.1 什么是多态

多态指的是同一操作作用于不同对象,可以产生不同的执行结果。

class Animal:
    def speak(self):
        pass  # 抽象方法

class Dog(Animal):
    def speak(self):
        print("汪汪汪")

class Cat(Animal):
    def speak(self): 
        print("喵喵喵")

def make_sound(animal: Animal):
    """同一函数,不同表现"""
    animal.speak()

# 使用多态
dog = Dog()
cat = Cat()

make_sound(dog)  # 输出:汪汪汪
make_sound(cat)  # 输出:喵喵喵

8.2 抽象类与接口

8.2.1 抽象类设计

class AC:
    """空调抽象类(接口)"""
    
    def cool_wind(self):
        """制冷(抽象方法)"""
        pass
    
    def hot_wind(self):
        """制热(抽象方法)"""
        pass
    
    def swing_l_r(self):
        """左右摆风(抽象方法)"""
        pass

class MideaAC(AC):
    """美的空调实现"""
    
    def cool_wind(self):
        print("美的空调核心制冷科技")
    
    def hot_wind(self):
        print("美的空调电热丝加热")
    
    def swing_l_r(self):
        print("美的空调无风感左右摆风")

class GreeAC(AC):
    """格力空调实现"""
    
    def cool_wind(self):
        print("格力空调变频省电制冷")
    
    def hot_wind(self):
        print("格力空调电热丝加热")
    
    def swing_l_r(self):
        print("格力空调静音左右摆风")

8.2.2 多态的应用

def use_ac(ac: AC):
    """使用空调(多态应用)"""
    ac.cool_wind()
    ac.swing_l_r()

# 使用不同的空调实现
midea = MideaAC()
gree = GreeAC()

use_ac(midea)  # 使用美的空调
use_ac(gree)   # 使用格力空调

九、综合案例实战

9.1 银行ATM系统面向对象设计

9.1.1 类设计

class Account:
    """账户类"""
    
    def __init__(self, account_id: str, name: str, balance: float = 0.0):
        self.__account_id = account_id      # 私有属性:账户ID
        self.name = name                   # 公开属性:姓名
        self.__balance = balance           # 私有属性:余额
    
    def get_balance(self) -> float:
        """获取余额"""
        return self.__balance
    
    def deposit(self, amount: float) -> bool:
        """存款"""
        if amount > 0:
            self.__balance += amount
            return True
        return False
    
    def withdraw(self, amount: float) -> bool:
        """取款"""
        if 0 < amount <= self.__balance:
            self.__balance -= amount
            return True
        return False

class ATM:
    """ATM机类"""
    
    def __init__(self):
        self.accounts: Dict[str, Account] = {}
        self.current_account: Optional[Account] = None
    
    def register_account(self, account_id: str, name: str) -> bool:
        """注册账户"""
        if account_id not in self.accounts:
            self.accounts[account_id] = Account(account_id, name)
            return True
        return False
    
    def login(self, account_id: str) -> bool:
        """登录账户"""
        if account_id in self.accounts:
            self.current_account = self.accounts[account_id]
            return True
        return False
    
    def operate(self):
        """主操作流程"""
        while True:
            print("\n=== ATM系统 ===")
            if self.current_account:
                print(f"当前用户:{self.current_account.name}")
                print("1. 查询余额 2. 存款 3. 取款 4. 退出登录")
            else:
                print("1. 注册 2. 登录 3. 退出")
            
            choice = input("请选择操作:")
            
            if not self.current_account:
                if choice == "1":
                    self._register()
                elif choice == "2":
                    self._login()
                elif choice == "3":
                    break
            else:
                if choice == "1":
                    self._check_balance()
                elif choice == "2":
                    self._deposit()
                elif choice == "3":
                    self._withdraw()
                elif choice == "4":
                    self.current_account = None

9.2 数据分析案例

9.2.1 数据读取类

import json
from typing import List, Dict, Union

class DataReader:
    """数据读取基类"""
    
    def __init__(self, file_path: str):
        self.file_path = file_path
        self.data: List[Dict] = []
    
    def read_data(self) -> bool:
        """读取数据(抽象方法)"""
        pass
    
    def process_data(self) -> List[Dict]:
        """处理数据"""
        return self.data

class JsonDataReader(DataReader):
    """JSON数据读取器"""
    
    def read_data(self) -> bool:
        try:
            with open(self.file_path, 'r', encoding='utf-8') as f:
                raw_data = f.read()
                self.data = json.loads(raw_data)
            return True
        except Exception as e:
            print(f"读取JSON数据失败:{e}")
            return False

class CsvDataReader(DataReader):
    """CSV数据读取器"""
    
    def read_data(self) -> bool:
        try:
            with open(self.file_path, 'r', encoding='utf-8') as f:
                headers = f.readline().strip().split(',')
                for line in f:
                    values = line.strip().split(',')
                    item = dict(zip(headers, values))
                    self.data.append(item)
            return True
        except Exception as e:
            print(f"读取CSV数据失败:{e}")
            return False

class DataAnalyzer:
    """数据分析器"""
    
    def __init__(self, reader: DataReader):
        self.reader = reader
        self.analysis_result: Dict = {}
    
    def analyze(self) -> Dict:
        """执行分析"""
        if self.reader.read_data():
            data = self.reader.process_data()
            self.analysis_result = self._perform_analysis(data)
            return self.analysis_result
        return {}
    
    def _perform_analysis(self, data: List[Dict]) -> Dict:
        """实际分析逻辑"""
        # 实现具体的分析逻辑
        return {"total": len(data), "analysis": "完成"}

十、面向对象最佳实践

10.1 设计原则

10.1.1 SOLID原则

  1. 单一职责原则:一个类只负责一个功能领域
  2. 开闭原则:对扩展开放,对修改关闭
  3. 里氏替换原则:子类可以替换父类
  4. 接口隔离原则:使用多个专门的接口
  5. 依赖倒置原则:依赖抽象而不是具体实现

10.2 代码组织建议

10.2.1 模块化组织

project/
├── models/          # 数据模型类
│   ├── __init__.py
│   ├── user.py      # 用户类
│   └── product.py   # 商品类
├── services/        # 业务逻辑类
│   ├── __init__.py
│   └── user_service.py
├── utils/          # 工具类
│   ├── __init__.py
│   └── file_util.py
└── main.py         # 主程序

10.2.2 文档字符串规范

class Student:
    """学生类
    
    用于管理学生的基本信息和学习行为
    """
    
    def __init__(self, name: str, age: int):
        """初始化学生对象
        
        Args:
            name: 学生姓名
            age: 学生年龄
        """
        self.name = name
        self.age = age
    
    def study(self, course: str) -> str:
        """学习课程
        
        Args:
            course: 课程名称
            
        Returns:
            学习结果描述
        """
        return f"{self.name}正在学习{course}"

通过系统学习面向对象编程,您已经掌握了现代编程的核心范式。面向对象编程能够帮助您编写出更加结构化、可维护和可扩展的代码。在实际项目中灵活运用这些概念,将大幅提升您的编程能力和代码质量。

posted @ 2026-01-23 15:27  FxorG  阅读(2)  评论(0)    收藏  举报