云计算百科
云计算领域专业知识百科平台

初识Python面向对象

一、引言:从杂乱的数据到规整的结构

在生活中,我们习惯于用“表格”来组织信息——入学登记表、员工信息表、商品清单……表格让杂乱的数据变得清晰有序。

在程序中,我们同样需要这种“规整”的数据组织方式。试想一下:如果要记录一名学生的姓名、年龄、班级、成绩等信息,用变量当然可以,但如果有100个学生,难道要定义100组变量吗?用列表或字典也可以,但数据结构松散,容易出错。

面向对象编程(Object-Oriented Programming, OOP) 正是为了解决这个问题而生的。它让我们可以在程序中设计“表格”(类) ,然后生产“表格”(对象) ,最后填写数据(属性赋值) ,完美模拟现实世界的数据组织方式。

本篇博客将带领大家从零开始,全面掌握Python面向对象编程的核心知识,包括类与对象、封装、继承、多态、类型注解等。

二、初识对象

2.1 现实世界 vs 程序世界

在现实世界中,生产一件产品通常遵循这样的流程:

  • 设计图纸:画出产品的结构和功能

  • 生产实体:根据图纸制造出实际产品

  • 投入使用:产品完成实际工作

  • 在程序世界中,面向对象编程遵循完全相同的逻辑:

  • 设计类(Class) :定义数据的结构和行为

  • 创建对象(Object) :根据类实例化出具体对象

  • 使用对象:调用对象的方法完成功能

  • 2.2 类的定义与对象的创建

    类(Class) 是“图纸”,定义了属性和行为。对象(Object) 是“实体”,是基于类创建的具体实例。

    # 定义一个学生类(设计图纸)
    class Student:
    # 成员变量(属性)
    name = None
    age = None

    # 成员方法(行为)
    def say_hi(self):
    print(f"大家好,我叫{self.name}!")

    # 创建对象(生产实体)
    stu = Student()
    stu.name = "张三" # 填写属性
    stu.say_hi() # 调用方法

    三、成员变量与成员方法

    3.1 成员变量(属性)

    在类中定义的变量称为成员变量,用于存储对象的数据。每个对象都有自己的成员变量副本,互不干扰。

    3.2 成员方法(行为)

    在类中定义的函数称为成员方法,用于描述对象的行为。成员方法与普通函数的区别在于:第一个参数必须是self。

    3.3 self关键字

    self是成员方法定义时必须填写的参数,它代表对象自身。

    class Student:
    name = None

    def say_hi(self):
    # self.name 访问当前对象的name属性
    print(f"大家好,我叫{self.name}!")

    def say_hi2(self, msg):
    print(f"大家好,我叫{self.name},{msg}")

    # 使用
    stu = Student()
    stu.name = "里斯"
    stu.say_hi() # self自动传入,无需手动传参
    stu.say_hi2("欢迎学习Python!")

    四、构造方法(init)

    4.1 什么是构造方法?

    __init__是Python类中的构造方法,在创建对象时会自动执行,主要用于初始化对象的属性。

    class Student:
    # 构造方法
    def __init__(self, name, age):
    self.name = name
    self.age = age
    print(f"学生{name}创建成功!")

    # 创建对象时自动调用__init__
    stu = Student("张三", 18) # 输出:学生张三创建成功!

    构造方法的特点:

    • 方法名必须是__init__(前后各两个下划线)

    • 第一个参数必须是self

    • 创建对象时自动调用

    • 传入的参数会自动传递给__init__

    4.2 构造方法的优势

    使用构造方法后,我们可以在创建对象的同时完成属性赋值,代码更简洁。

    # 不使用构造方法(传统方式)
    stu = Student()
    stu.name = "张三"
    stu.age = 18

    # 使用构造方法(推荐)
    stu = Student("张三", 18) # 一步到位

    五、内置魔法方法

    Python类中有一些以双下划线开头和结尾的特殊方法,被称为魔法方法。它们会在特定情况下自动被调用。

    5.1 str:字符串方法

    控制对象被打印时的显示格式。

    class Student:
    def __init__(self, name, age):
    self.name = name
    self.age = age

    def __str__(self):
    return f"【学生姓名:{self.name},年龄:{self.age}】"

    stu = Student("张三", 18)
    print(stu) # 【学生姓名:张三,年龄:18】

    5.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("张三", 18)
    stu2 = Student("王五", 22)
    print(stu1 < stu2) # True(按年龄比较)

    5.3 eq:等于比较

    控制对象使用==运算符时的行为。

    def __eq__(self, other):
    return self.age == other.age

    stu1 = Student("张三", 18)
    stu2 = Student("李四", 18)
    print(stu1 == stu2) # True(年龄相同)

    六、封装

    6.1 什么是封装?

    封装是面向对象三大特性之一(封装、继承、多态)。它指的是将属性和行为封装在类中,并对用户隐藏某些内部细节。

    现实世界中的事物,并不是所有属性和行为都是公开的。比如手机的内部电路、操作系统的内核代码,用户不需要知道,也不应该随意访问。

    6.2 私有成员

    在Python中,使用双下划线开头的变量或方法,表示私有成员,只能在类内部使用,外部无法访问。

    class Phone:
    # 私有成员变量
    __brand = "华为"
    __voltage = 4.0

    # 私有成员方法
    def __check_voltage(self):
    if self.__voltage < 5:
    print("电压不足")

    # 公开方法
    def call(self):
    self.__check_voltage() # 内部可以调用私有方法
    print("正在通话中")

    phone = Phone()
    # print(phone.__brand) # 错误!私有成员外部不可访问
    # phone.__check_voltage() # 错误!
    phone.call() # 正确!公开方法可以访问私有成员

    封装的意义:保护数据安全,隐藏实现细节,提供清晰的外部接口。

    七、继承

    7.1 单继承

    继承允许子类获得父类的所有成员变量和方法(私有成员除外),实现代码复用。

    # 父类
    class Phone:
    producer = "华为"

    def call(self):
    print("正在通话中")

    # 子类(单继承)
    class Phone2025(Phone):
    def call_6G(self):
    print("正在6G通话中")

    # 使用
    phone = Phone2025()
    print(phone.producer) # 华为(继承自父类)
    phone.call() # 正在通话中(继承自父类)
    phone.call_6G() # 正在6G通话中(自己的)

    7.2 多继承

    Python支持多继承,一个子类可以继承多个父类。

    class NFCReader:
    producer = "苹果工厂1"
    def read(self):
    print("正在读取数据")

    class RemoteControl:
    producer = "苹果工厂2"
    def control(self):
    print("正在遥控")

    # 多继承
    class MyPhone(NFCReader, RemoteControl):
    pass

    my_phone = MyPhone()
    print(my_phone.producer) # 苹果工厂1(优先继承第一个父类)
    my_phone.read() # 正在读取数据
    my_phone.control() # 正在遥控

    多继承的同名冲突:当多个父类有同名成员时,按继承顺序从左到右,优先保留先继承的。

    7.3 pass占位语句

    pass是Python中的占位语句,用于保证代码结构的完整性,表示暂时为空,稍后补充。

    class MyPhone(NFCReader, RemoteControl):
    pass # 暂时不写任何内容,保持类定义完整

    八、复写父类成员与super()

    8.1 复写(Override)

    如果子类对父类的成员不满意,可以在子类中重新定义同名的成员,覆盖父类的版本。

    class Phone:
    producer = "SJ"
    def call(self):
    print("正在通话中")

    class MyPhone(Phone):
    # 复写父类属性
    producer = "PYT"
    # 复写父类方法
    def call(self):
    print("正在5G通话中")
    print("5G升级中!")

    my_phone = MyPhone()
    print(my_phone.producer) # PYT(子类的值)
    my_phone.call() # 正在5G通话中(子类的方法)

    8.2 调用被复写的父类成员

    在子类中,如果复写了父类成员,但仍需使用父类的版本,有两种方式:

    class MyPhone(Phone):
    def call(self):
    print("正在5G通话中")

    # 方式1:使用父类名调用
    Phone.call(self)
    print(f"父类的厂商:{Phone.producer}")

    # 方式2:使用super()调用
    super().call()
    print(f"父类的厂商:{super().producer}")

    九、类型注解

    9.1 为什么需要类型注解?

    Python是动态类型语言,变量的类型在运行时才确定。这在带来灵活性的同时,也让代码的可读性和IDE提示受到影响。

    类型注解可以显式地说明变量、函数参数和返回值的类型,帮助IDE提供更好的代码提示,也方便其他开发者理解代码。

    9.2 变量的类型注解

    # 基本类型注解
    a: int = 10
    name: str = "张三"
    price: float = 9.9
    is_ok: bool = True

    # 容器类型注解
    my_list: list[int] = [1, 2, 3, 4]
    my_tuple: tuple[int, str] = (1, "hello")
    my_dict: dict[str, int] = {"age": 18}

    # 类对象注解
    class Student:
    pass
    stu: Student = Student()

    9.3 函数(方法)的类型注解

    # 参数类型注解 + 返回值类型注解
    def add(x: int, y: int) -> int:
    return x + y

    result = add(1, 2) # IDE会提示result是int类型

    9.4 Union类型

    当变量可能是多种类型之一时,使用Union。

    from typing import Union

    # 列表中的元素可以是int或str
    my_list: list[Union[int, str]] = [1, 2, "3", "4"]

    # 函数参数可以是int或str,返回值也可以是int或str
    def process(data: Union[int, str]) -> Union[int, str]:
    return data

    类型注解的特点:

    • 仅仅是提示性的,不是强制性的

    • 不会影响程序的运行

    • 主要作用是提高代码可读性和IDE支持

    十、多态与抽象类

    10.1 什么是多态?

    多态(Polymorphism)是指同一个行为(方法),传入不同的对象,得到不同的状态和结果。

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

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

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

    def make_noise(animal):
    animal.speak() # 传入不同对象,发出不同声音

    make_noise(Dog()) # 汪汪汪
    make_noise(Cat()) # 喵喵喵

    10.2 抽象类(接口)

    抽象类是包含抽象方法的类,它定义了“有哪些方法”,但不实现具体细节,由子类自行决定如何实现。

    在Python中,抽象方法的方法体通常写为pass。

    class AC:
    def cool_wind(self):
    """制冷"""
    pass

    def hot_wind(self):
    """制热"""
    pass

    class GREE(AC):
    def cool_wind(self):
    print("格力制冷")
    def hot_wind(self):
    print("格力制热")

    class Midea(AC):
    def cool_wind(self):
    print("美的制冷")
    def hot_wind(self):
    print("美的制热")

    抽象类的设计思想:

    • 父类定义标准(有哪些方法)

    • 子类实现细节(如何实现)

    • 面向接口编程,而非具体实现

    十一、综合实战:学生信息录入系统

    综合运用类、构造方法、__str__、列表等知识,完成一个学生信息录入系统。

    class Student:
    def __init__(self, name, age, address):
    self.name = name
    self.age = age
    self.address = address

    def __str__(self):
    return f"【学生姓名:{self.name},年龄:{self.age},地址:{self.address}】"

    def main():
    students = []
    total = 3

    for i in range(total):
    print(f"当前录入第{i+1}位学生信息,总共需录入{total}位")
    name = input("请输入学生姓名:")
    age = input("请输入学生年龄:")
    address = input("请输入学生地址:")

    stu = Student(name, age, address)
    students.append(stu)
    print(f"学生{i+1}信息录入完成:{stu}")

    print("\\n所有学生信息如下:")
    for student in students:
    print(student)

    if __name__ == "__main__":
    main()

    十二、总结

    本篇博客系统学习了Python面向对象编程的核心知识:

    主题核心内容
    类与对象 类是图纸,对象是实体
    成员方法 必须包含self参数
    构造方法 __init__,创建对象时自动执行
    魔法方法 __str__、__lt__、__eq__等
    封装 私有成员以__开头,外部不可访问
    继承 单继承、多继承,pass占位
    复写 子类重定义父类成员,super()调用父类
    类型注解 变量、函数参数、返回值、Union
    多态 同一行为,不同对象产生不同状态
    抽象类 父类定义标准,子类实现细节

    面向对象编程让我们的程序更加结构化、易维护、易扩展。它模拟了现实世界的事物组织方式,是大型项目开发中不可或缺的编程范式。

    赞(0)
    未经允许不得转载:网硕互联帮助中心 » 初识Python面向对象
    分享到: 更多 (0)

    评论 抢沙发

    评论前必须登录!