Python编程基础八(面向对象)

第一部分:初识对象

一、生活中数据的组织问题

学校开学收集学生信息时,自由填表常导致:

  • 格式混乱(”我叫林军点,今年31岁” vs “姓名:周杰轮”)
  • 信息缺失(籍贯未填写)
  • 数据无序难以管理

标准化解决方案:

  1. 设计统一登记表模板(姓名/性别/国籍/籍贯/年龄)
  2. 打印分发标准表格
  3. 回收规范数据

二、程序中数据组织的困境

# 不良示范:混合数据结构

stu1 = "林俊杰,男,中国,山东,31"

stu2 = {"name": "周杰轮"}

stu3 = ["周杰轮", "男", None, None, 31]

三、面向对象解决方案

核心思想:设计模板 → 批量生产 → 规范填写

现实步骤程序实现代码示例
设计表格创建类class Student:
打印表格实例化对象stu1 = Student()
填写表格属性赋值stu1.name = "林俊杰"

四、类与对象实践

class Student:

    name = None #

    gender = None

    nationality = None

    native_place = None

    age = None 
# 创建实例

stu1 = Student() # 填写信息

stu1.name = "林俊杰"

stu1.gender = "男"

stu1.nationality = "中国"

stu1.native_place = "山东省"

stu1.age = 31

五、面向对象优势对比

传统方式面向对象
数据结构混乱统一规范
维护困难易于扩展
无固定格式类型安全
难以批量处理支持批量操作


第二部分:类的成员方法

一、成员方法基础

class Student: # 类属性定义

   name=None

   def say_hi(self): # 必须包含self参数

         print(f"大家好,我是{self.name}") # 通过self访问成员变量,

# 创建对象并调用方法

stu = Student()

stu.name = "陈军杰"

stu.say_hi() # 输出:大家好,我是陈军杰

二、self关键字的秘密

  1. 自动传递机制:Python在调用方法时自动将对象实例作为self传入
  2. 参数传递规则:调用时只需传递self后的参数
  3. 访问限制:不使用self将无法访问类的成员变量

三、方法升级-带参方法

新增say_hi2(self, msg)

参数区别:msg需要显式传递,self自动传递

演示:

class Student:

   name = None #姓名

   gender = None#性别

   nationality = None # 国籍

   native_place = None #籍贯

   age = None# 年龄

   def say_hi(self):

      print(f"我是{self.name}")

   def say_hi2(self,msg):

      print(f"大家好我是{self.name},{msg}")

stu_1 =Student()

stu_1.name="林俊杰"

stu_1.say_hi2("不错呦!")

四、方法设计原则

原则说明示例
高内聚每个方法只完成单一功能calculate_gpa() 只处理成绩计算
低耦合方法间尽量减少依赖信息展示方法不修改数据
合理命名动词开头,见名知意get_age() 优于 data1()

第三部分:类与对象

一、现实事物抽象方法论

  • 1. 现实世界的事物和类

属性与行为: 现实世界中的事物可以归纳为两个特征,即属性和行为。例如,做核酸的属性包括何时何地谁去做,行为包括登记检测查结果;手机的属性包括长宽高重量厂商型号,行为包括打电话上网拍照。

类描述事物: 类同样具有属性和行为,因此使用类描述现实世界中的事物是非常合适的。

  • 2.为什么创建对象

设计图纸与实体: 类是程序中的设计图纸,而对象是基于图纸生产出来的具体实体。类只是一种描述,真正工作的是对象。

面向对象编程: 这种通过类创建对象并使用对象进行编程的思想,就是面向对象编程。

  • 3.示例——用类与对象描述显示事物,闹钟。
import winsound

class AlarmClock:

   model = None # 属性:型号

   price = None # 属性:价格

   def ring(self): # 行为:响铃

      winsound.Beep(2000, 3000) # 2000Hz频率响3秒

# 创建实体对象

my_clock = AlarmClock()

my_clock.model=“小米智能闹钟”

my_clock.price=149

my_clock.ring()

二、面向对象三大特征初探

  1. 封装:将闹钟的电路原理隐藏在内部
  2. 继承:智能闹钟继承基础闹钟功能
  3. 多态:不同品牌闹钟有不同的响铃方式

三、对象生命周期图解

[类蓝图] → (实例化) → [对象实例] → (调用方法) → [行为执行]


第四部分:构造方法与魔术方法

一、构造方法

class Student:

   name=None #当有构造函数赋值时,可省略

   age=None #当有构造函数赋值时,可省略

   tel=None #当有构造函数赋值时,可省略

   def __init__(self, name, age, tel): # 构造方法

      self.name = name # 属性初始化

      self.age = age self.tel = tel print("学生对象已创建")

# 创建对象更高效

stu = Student("周杰轮", 31, "119") # 一行完成初始化

二、魔术方法大全

方法触发场景典型应用
__str__print(obj)友好对象描述
__lt__obj1 < obj2年龄比较
__eq__obj1 == obj2学号判等
__del__对象销毁时资源释放

三、构造方法最佳实践

  1. 必填参数放前面
  2. 可选参数设置默认值
  3. 进行基础校验

四、特殊方法实战

class EnhancedStudent(Student):

   def __str__(self):

      return f"学生[{self.name}],年龄{self.age}岁"

   def __lt__(self, other):

      return self.age < other.age

   def __eq__(self, other):

      return self.tel == other.tel

# 使用示例

stu1 = EnhancedStudent("林俊杰", 40, "138001")

stu2 = EnhancedStudent("周杰伦", 41, "138002")

print(stu1) # 输出:学生[林俊杰],年龄40岁

print(stu1 < stu2) # 输出:True


第五部分:封装

一、封装的双重含义

  1. 数据封装:将属性隐藏在类内部
  2. 行为封装:对外暴露安全接口

二、私有成员

class BankAccount: 

def __init__(self, owner, balance):

self.owner = owner # 公开属性

self.__balance = balance # 私有属性

def deposit(self, amount):

if amount > 0:

self.__balance += amount

def get_balance(self):

return self.__balance # 通过方法访问私有属性

# 测试用例

account = BankAccount("张三", 1000)
account.__balance = 2000
account.deposit(500)

print(account.get_balance()) # 输出:1500

account.__balance = 2000 # 实际创建了新属性,不影响真实余额

三、访问控制等级

类型命名规则可见范围
公开成员无下划线类内外均可访问
保护成员_单下划线约定俗成的内部使用
私有成员__双下划线仅类内部访问

四、封装设计原则

  1. 最小暴露原则:只公开必要接口
  2. 防御性编程:在方法中进行参数校验
  3. 保持一致性:修改内部实现不影响外部调用

第六部分:继承与方法复写

继承优势:提高代码复用性,减少重复劳动,使代码结构更清晰

一、单继承示例

class Animal:
def __init__(self, name):
self.name = name
def eat(self):
print(f"{self.name}正在进食")
class Cat(Animal):
def meow(self):
print("喵喵叫")
class cattest(Animal):
pass
# 使用继承
tom = Cat("Tom")
tom.eat() # 继承自父类
tom.meow() # 子类特有方法

pass关键字:用于占位,保证语法完整性,表示该类没有新增内容

二、多继承示例

class Camera:
def take_photo(self):
print("拍照功能")
class Phone:
def make_call(self):
print("打电话")
class SmartPhone(Camera, Phone):
def unlock(self):
print("面部解锁")
# MRO(方法解析顺序)演示
print(SmartPhone.mro()) # 显示继承顺序

注意事项:

同名成员处理:当多个父类有同名属性或方法时,按照继承顺序(从左到右)确定优先级,方法调用同样遵循从左到右的继承顺序原则.

三、复写父类成员和调用父类成员

1.复写

定义:当子类继承父类的成员属性和方法后,若对继承内容不满意,可在子类中重新定义同名属性或方法的行为。

实现方式:直接在子类中声明与父类同名的成员即可完成复写,无需特殊语法标记。

关键特点:复写后子类对象调用成员时,优先使用子类版本的内容

2.调用父类同名成员

问题场景:复写后仍需访问被覆盖的父类原始成员

核心原则:需要通过特殊语法显式调用,直接使用同名成员默认访问子类版本

调用方式:类名调用、super调用

3.示例

class Cat():
    def meow(self):
        print("喵喵叫")
class SmartCat(Cat):
    def eat(self):
        super().meow()  # 先调用父类方法
        print("并且正在吃猫粮")

    def meow(self):
        print("电子喵喵叫")

# 测试复写
smart_cat = SmartCat()
smart_cat.meow()
smart_cat.eat()

四、继承设计指南

情景解决方案
需要扩展功能单继承+方法复写
组合多个功能多继承
避免菱形继承使用Mixin类
接口标准化抽象基类

第七部分:类型注解

一、普通类型注解深度解析

使用建议与注意事项

推荐场景:

无法直接看出变量类型时(如随机数结果、JSON解析结果)

函数返回值类型不明确时

不必要场景:

显式赋值的简单类型(如var: int = 10)

类型显而易见的情况

重要特性

非强制性:

注解类型与实际类型不符不会报错(如var: int = “str”)

仅是提示功能,不影响程序运行python

from typing import Union
#标准语法:变量: 类型 = 值
var_1: int = 10
var_2: float = 3.1415926
var_3: bool = True
var_4: str = "itheima"

class Student:
pass
stu: Student = Student()

#容器类型注解
#简易注解:
#详细注解:
#列表:
my_list: list[int] = [1,2,3]
#元组:
my_tuple: tuple[int,str,bool] = (1,"itheima",True)
#字典:
my_dict: dict[str,int] = {"itheima":666}


#注释形式语法

var_5 = random.randint(1,10) # type: int
var_6 = json.loads(data) # type: dict[str,int]
var_7 = Student() # type: Student



二、Union联合类型注解

定义: 使用Union可以定义联合类型注解,用于描述变量或函数参数/返回值可能包含的多种类型。

应用场景: 当需要描述混合类型的数据结构时使用,如列表中同时包含int和str类型元素。

导入方式:

from typing import Union

列表注解:

my_list: list[Union[int, str]] = [1, 2, "itheima", "itcast"]

字典注解:

my_dict: dict[str, Union[str, int]] = {"name":"周杰轮", "age":31}

注意事项:

Union的U必须大写

需要先导入才能使用

适用于变量、函数形参和返回值注解

第八部分:多态

一、多态定义与机制

定义:多态指多种状态,即完成某个行为时,使用不同对象会得到不同状态

实现方式:

父类定义方法但不实现(pass)

子类继承并重写父类方法

关键机制:

函数形参声明接收父类对象(类型注解)

实际传入子类对象进行工作

二、代码示例

class AC:
def cool_wind(self):
pass
def hot_wind(self):
pass
def swing_l_r(self):
pass

class midea_AC(AC):
def cool_wind(self):
print("美的空调制冷")
def hot_wind(self):
print("美的空调制热")
def swing_l_r(self):
print("美的空调摆风")

class GELE_AC(AC):
def cool_wind(self):
print("格力空调制冷")
def hot_wind(self):
print("格力空调制冷")
def swing_l_r(self):
print("格力空调制冷")


def make_cool(ac:AC):
ac.cool_wind()

midea_ac=midea_AC()
geli_ac=GELE_AC()

make_cool(midea_ac)
make_cool(geli_ac)

二、多态设计优势

优势说明
接口统一不同对象相同方法调用
扩展性强新增子类无需修改父类
代码灵活运行时动态确定对象类型
易于测试可mock对象进行单元测试


全篇总结:面向对象编程核心要点梳理

一、面向对象三大支柱

特性核心价值典型应用场景
封装数据保护与接口规范化用户密码存储、硬件驱动封装
继承代码复用与体系扩展游戏角色系统、UI组件库
多态接口统一与灵活扩展支付系统对接、文件格式解析

二、学习路径图谱

类与对象基础 → 成员方法 → 构造方法 → 魔术方法 → 封装 → 继承体系 → 类型系统 → 设计模式

三、核心优势总结

  1. 工程化管理:通过类模块化组织代码
  2. 高复用性:继承机制减少重复代码
  3. 易维护性:封装保护内部实现细节
  4. 强扩展性:多态支持系统灵活扩展

综合案例:智能家居控制系统开发

一、系统需求分析

  1. 支持多种设备类型(照明/空调/安防)
  2. 统一控制接口
  3. 设备状态实时反馈
  4. 能耗统计功能

二、类结构设计

from typing import List, Dict
from abc import ABC, abstractmethod

class SmartDevice(ABC):
    """智能设备基类"""
    def __init__(self, device_id: str, power_consumption: float):
        self.__device_id = device_id  # 私有属性
        self._power_used = 0.0  # 保护属性
        self.power_rate = power_consumption  # 公开属性
        
    @abstractmethod
    def operate(self) -> None:
        """设备操作抽象方法"""
        pass
    
    @property
    def device_id(self) -> str:
        """只读属性访问"""
        return self.__device_id
    
    def energy_report(self) -> Dict[str, float]:
        """能耗报告(模板方法)"""
        return {
            "device_id": self.__device_id,
            "total_energy": self._power_used
        }

class SmartLight(SmartDevice):
    """智能照明设备"""
    def __init__(self, device_id: str, brightness: int = 50):
        super().__init__(device_id, 0.1)  # 继承构造方法
        self.__brightness = brightness  # 私有属性
        
    def operate(self, level: int) -> None:
        """实现多态方法"""
        if 0 <= level <= 100:
            self.__brightness = level
            self._power_used += self.power_rate * (level/10)
            print(f"照明{self.device_id}亮度调整为{level}%")
            
    def current_status(self) -> Dict[str, Union[str, int]]:
        """扩展方法"""
        return {
            "device_id": self.device_id,
            "type": "照明",
            "brightness": self.__brightness
        }

class SmartAC(SmartDevice):
    """智能空调设备"""
    def __init__(self, device_id: str):
        super().__init__(device_id, 2.5)
        self.__temperature = 26
        
    def operate(self, temp: int) -> None:
        """实现多态方法"""
        if 16 <= temp <= 30:
            self.__temperature = temp
            self._power_used += self.power_rate
            print(f"空调{self.device_id}设置为{temp}℃")

class HomeController:
    """家居控制中心"""
    def __init__(self):
        self.__devices: List[SmartDevice] = []
        
    def add_device(self, device: SmartDevice) -> None:
        """添加设备(类型注解)"""
        self.__devices.append(device)
        
    def batch_control(self, operation: Dict[str, int]) -> None:
        """批量控制(多态应用)"""
        for device in self.__devices:
            if isinstance(device, SmartLight):
                device.operate(operation.get("light_level", 50))
            elif isinstance(device, SmartAC):
                device.operate(operation.get("ac_temp", 26))
                
    def generate_report(self) -> List[Dict]:
        """生成报告(统一接口)"""
        return [d.energy_report() for d in self.__devices]

三、系统测试演示

# 初始化系统
controller = HomeController()

# 添加设备
living_room_light = SmartLight("L-101")
bedroom_ac = SmartAC("AC-202")
controller.add_device(living_room_light)
controller.add_device(bedroom_ac)

# 批量控制
controller.batch_control({
"light_level": 75,
"ac_temp": 24
})

# 查看状态
print(living_room_light.current_status())
# 输出:{'device_id': 'L-101', 'type': '照明', 'brightness': 75}

# 生成能耗报告
print(controller.generate_report())
# 输出:[{'device_id': 'L-101', 'total_energy': 0.75},
# {'device_id': 'AC-202', 'total_energy': 2.5}]

四、案例知识点解析

知识点应用场景代码示例
抽象类定义设备标准接口SmartDevice基类
封装保护设备ID和能耗数据__device_id私有属性
继承设备类型继承体系SmartLight继承SmartDevice
多态统一控制不同设备operate()方法的不同实现
类型注解参数类型提示add_device(device: SmartDevice)
魔术方法状态报告生成energy_report()模板方法
访问控制属性保护机制@property装饰器的使用