Python—面向对象

面向对象

一、初识对象

  1. 设计类(class),相当于设计表格
  2. 创建对象,相当于打印生产表格
  3. 对象赋值属性,相当于填写表格
python 复制代码
# 创建对象,相当于设计一张登记表
class Student:
    name = None
    gender = None
    age = None

# 创建对象,相当于打印一张表
stu_1 = Student()

# 为对象属性赋值,相当于填表
stu_1.name = "周杰伦"
stu_1.gender = "M"
stu_1.age = 22

# 获取对象中记录的信息
print(stu_1.name)
print(stu_1.gender)
print(stu_1.age)

二、成员方法

1、类的定义和使用

类的使用语法

python 复制代码
class 类名称:
    类的属性
    类的行为
  • class是关键字,表示要定义类了
  • 类的属性,即定义在类中的变量(成员变量)
  • 类的行为,即定义在类中的函数(成员方法)

创建类对象的语句:

python 复制代码
对象 = 类名称()

成员方法定义语法

python 复制代码
def 方法名(self,形参1,......,形参N):
    方法体
  • self关键字是成员方法定义时,必须填写的,表示类对象自身的意思
  • 当我们使用类对象第哦啊用方法的时候,self会自动被Python传入
  • 在方法内部,想要访问类的成员变量,必须使用self
python 复制代码
# 创建对象,相当于设计一张登记表
class Student:
    name = None
    gender = None
    age = None

    def say_hello(self):
        print(f"Hello World,我是{self.name}")


# 创建对象,相当于打印一张表
stu_1 = Student()


# 为对象属性赋值,相当于填表
stu_1.name = "周杰伦"
stu_1.gender = "M"
stu_1.age = 22

# 获取对象中记录的信息
stu_1.say_hello()

2、类和方法

类可以包含属性和行为

类是程序中的"设计图纸"

面向对象变成是使用对象进行编程,即,射设计类,基于类创建对象

二、构造方法

Python类可以使用:__init__()方法,称之为构造方法

可以实现:

  • 在创建类对象(构建类)的时候,会自动执行
  • 在创建类对象(构建类)的时候,将传入参数自定传递给__init__方法使用
python 复制代码
class Student:
    def say_hello(self):
        print(f"Hello World,我是{self.name}")

    def __init__(self, name, gender, age):
        # 具有赋值和定义的功能,之前的定义可以省略
        self.name = name
        self.gender = gender
        self.age = age
        print("Student类创建了一个对象")


stu_1 = Student("周杰伦", 'M', 22)

运行结果:

三、常见的类内置方法

__init__构造方法就是Python类内置的方法之一

这些内置的类方法,各自有各自特殊的功能,这些内置方法我们称之为:魔术方法

常见魔术方法:

  • __init__:构造方法

  • __str__:字符串方法

    python 复制代码
    class Student:
        def __init__(self, name, age, where):
            self.name = name
            self.age = age
            self.where = where
    
    
    student = Student("周杰伦", 18, "上海")
    print(student)
    # 结果:<__main__.Student object at 0x000001FB33268C20>

    当类对象需要被转换成字符串的时候,会输出内存地址

    内存地址不是我们想要的,就可以通过__str__方法,控制类转换为字符串的行为

    ​ 方法名:__str__

    ​ 返回值:字符串

    ​ 内容:自行定义

    python 复制代码
    class Student:
        def __init__(self, name, age, where):
            self.name = name
            self.age = age
            self.where = where
    
        def __str__(self):
            return f'我是{self.name},我{self.age}岁,我现在住在{self.where}'
    
    
    student = Student("周杰伦", 18, "上海")
    print(student)
    # 结果:我是周杰伦,我18岁,我现在住在上海
  • __lt__:大于、小于符号比较

    python 复制代码
    class Student:
        def __init__(self, name, age, where):
            self.name = name
            self.age = age
            self.where = where
    
    student1 = Student("周杰伦", 18, "上海")
    student2 = Student("林俊杰", 20, "北京")
    print(student1 < student2)
    # 结果:
    # Traceback (most recent call last):
    #   File "D:\study\pycharm\pycharm_project\study.py", line 306, in <module>
    #     print(student1 < student2)
    #           ^^^^^^^^^^^^^^^^^^^
    # TypeError: '<' not supported between instances of 'Student' and 'Student'

    直接将2个对象进行比较是不可以的,但是在类中实现__lt__方法,即可同时完成:小于和大于符号的2种比较

    ​ 方法名:__lt__

    ​ 传入参数:other,另一个对象

    ​ 返回值:True或False

    ​ 内容:自行定义

    python 复制代码
    class Student:
        def __init__(self, name, age, where):
            self.name = name
            self.age = age
            self.where = where
    
        def __lt__(self, other):
            return self.age < other.age
    
    
    student1 = Student("周杰伦", 18, "上海")
    student2 = Student("林俊杰", 20, "北京")
    print(student1 < student2)  # 结果:True
    print(student1 > student2)  # 结果:False
  • __le__:小于等于、大于等于符号比较

    相较于__lt__多了等于的比较

    ​ 方法名:__le__

    ​ 传入参数:other,另一个对象

    ​ 返回值:True或False

    ​ 内容:自行定义

    python 复制代码
    class Student:
        def __init__(self, name, age, where):
            self.name = name
            self.age = age
            self.where = where
    
        def __le__(self, other):
            return self.age < other.age
    
    
    student1 = Student("周杰伦", 18, "上海")
    student2 = Student("林俊杰", 20, "北京")
    print(student1 <= student2)  # 结果:True
    print(student1 >= student2)  # 结果:False
  • __eq__:==符号比较

    正常来说,对象之前比较的是内存地址,也就是说==比较,结果一定是False

    python 复制代码
    class Student:
        def __init__(self, name, age, where):
            self.name = name
            self.age = age
            self.where = where
    
    
    student1 = Student("周杰伦", 18, "上海")
    student2 = Student("周杰伦", 18, "上海")
    print(student1 == student2)  # 结果:False

    使用__eq__方法,按照自己的想法来决定2个对象是否相等

    ​ 方法名:__eq__

    ​ 传入参数:other,另一个对象

    ​ 返回值:True或False

    ​ 内容:自行定义

    python 复制代码
    class Student:
        def __init__(self, name, age, where):
            self.name = name
            self.age = age
            self.where = where
    
        def __eq__(self, other):
            return self.age == other.age
    
    
    student1 = Student("周杰伦1", 18, "上海")
    student2 = Student("周杰伦2", 18, "上海")
    student3 = Student("林俊杰3", 20, "北京")
    print(student1 == student2)  # 结果:True
    print(student1 == student3)  # 结果:False

四、封装

封装指的是将现实事务的:属性、行为,封装到类中,描述为:成员变量、成员方法,从而完成程序对于现实世界的描述

1、私有成员

类中提供私有成员的形式来支持,私有成员变量、私有成员方法

命名规则

  • 私有成员变量:变量名以__开头(两个下划线)
  • 私有成员方法:方法名以__开头(两个下划线)

访问限制

  • 类对象无法访问私有成员
  • 类中的其他成员可以访问私有成员

使用私有成员

  • 错误使用方法:
python 复制代码
class phone:
    # 序列号
    IMEI = None
    # 厂商
    producer = None
    # 当前电压
    __current_voltage = None

    def call_by_5g(self):
        print("5g通话已开启")

    def __keep_single_core(self):
        print("让cpu以单核模式运行以节约电量")


# 创建对象
phone = phone()
# 使用私有方法
# 报错
phone.__keep_single_core()
# 私有变量赋值
# 不报错,但无效
phone.__current_voltage = 10
# 获取私有变量值
# 报错,无法使用
print(phone.__current_voltage)
  • 正确使用方法
python 复制代码
class phone:
    # 序列号
    IMEI = None
    # 厂商
    producer = None
    # 当前电压
    __current_voltage = 0.1

    def __keep_single_core(self):
        print("让cpu以单核模式运行以节约电量")

    def call_by_5g(self):
        if self.__current_voltage >= 1:
            print("5g通话已开启")
        else:
            self.__keep_single_core()
            print("电量不足,无法使用5g通话,并设置为单核运行进行省电")


# 创建对象
phone = phone()
phone.call_by_5g()

练习题

设计带有私有成员的手机

设计一个手机类,内部包含:

  • 私有成员变量__is_5g_enable,类型为bool,True表示开启5g,False表示关闭5g
  • 私有成员方法:__check_5g(),会判断私有成员__is_5g_enable的值
    • 若为True,打印输出:5g开启
    • 若为False,打印输出:5g开启,使用4g网络
  • 公开成员方法:call_by_5g(),调用它会执行
    • 调用私有成员方法:__check_5g(),判断5g网络状态
    • 打印输出:正在通话中

运行结果:5g关闭,使用4g网络

​ 正在通话中...

通过完成这个类的设计和使用,体会封装中私有成员的作用

  • 对用户公开的,call_by_5g()方法
  • 对用户隐藏的,__is_5g_enable私有变量和__check_5g私有成员
python 复制代码
# 设计一个类,用来描述手机
class Phone:
    # 提供私有成员变量:__is_5g_enable
    __is_5g_enable = True

    # 提供私有成员方法:
    def __check_5g(self):
        if self.__is_5g_enable:
            print("5g开启")
        else:
            print("5g关闭,使用4g网络")

    # 提供公开成员方法:call_by_5g()
    def call_by_5g(self):
        self.__check_5g()
        print("正在通话中...")


phone = Phone()
phone.call_by_5g()

五、继承

继承:将父类那里继承(复制)来成员变量和成员方法(不含私有)

1、继承的基本语法

python 复制代码
class 类名(父类名)
	类内容体

2、单继承

python 复制代码
# 单继承示例
class Phone:
    # 序列号
    IMEI = None
    # 厂商
    producer = "RAY"

    def call_by_4g(self):
        print("4g通话")


class Phone2026(Phone):
    # 面部识别id
    face_id = '10001'

    def call_by_5g(self):
        print("2026年性能功能:5g通话")


phone = Phone2026()
print(phone.producer)
phone.call_by_4g()
phone.call_by_5g()

3、多继承

Python中类之间也支持多继承,即:一个类,可以继承多个父类

python 复制代码
class 类名(父类1, 父类2, ......, 父类N):
    类内容体
python 复制代码
# 多继承示例:
class Phone:
    # 序列号
    IMEI = None
    # 厂商
    producer = "RAY"

    def call_by_4g(self):
        print("4g通话")


class Phone2026(Phone):
    # 面部识别id
    face_id = '10001'

    def call_by_5g(self):
        print("2026年性能功能:5g通话")


phone = Phone2026()
print(phone.producer)
phone.call_by_4g()
phone.call_by_5g()


class NFCReader:
    nfc_type = "第五代"
    producer = "Ray"

    def read_card(self):
        print("NFC读卡")

    def write_card(self):
        print("NFC写卡")


class RemoteControl:
    rc_type = "红外遥控"

    def control(self):
        print("红外遥控已开启")


class MyPhone(Phone, NFCReader, RemoteControl):
    # pass是占位语句,用来保证函数(方法)或类定义的完整性,表示无内容、空的意思
    pass


phone = MyPhone()
phone.call_by_4g()
phone.read_card()
phone.write_card()
phone.control()
# 运行结果:
# RAY
# 4g通话
# 2026年性能功能:5g通话
# 4g通话
# NFC读卡
# NFC写卡
# 红外遥控已开启

多继承注意事项:

多个父类中,如果有同名的成员,那么默认以继承顺序(从左到右)为优先级。即:先继承的保留,后继承的覆盖

4、复写和使用父类成员

复写

子类继承父类的成员属性和成员方法后,如果对其"不满意",那么可以进行复写。即:在子类中重新定义同名的属性或方法即可。

python 复制代码
# 复写
class phone:
    IMEI = None
    producer = "RAY"

    def call_by_5g(self):
        print("父类的5g通话")


# 定义子类,复写父类成员
class MyPhone(phone):
    # 复写父类的成员属性
    producer = "HAHA"

    def call_by_5g(self):
        print("子类的5g通话")


phone = MyPhone()
phone.call_by_5g()
print(phone.producer)
# 运行结果:
# 子类的5g通话
# HAHA

调用父类同名成员

一旦复写父类成员,那么类对象调用成员的时候,就会调用复写后的新成员。如果需要使用被复写的父类的成员,需要特殊的调用方式:

方式1:

调用成员变量:父类名.成员变量

使用成员方法:父类名.成员方法(self)

方法2:

使用super()调用父类方法

使用成员变量:super().成员变量

使用成员方法:super.成员方法()

python 复制代码
#调用示例
class phones:
    IMEI = None
    producer = "RAY"

    def call_by_5g(self):
        print("父类的5g通话")


# 定义子类,复写父类成员
class MyPhone(phones):
    # 复写父类的成员属性
    producer = "HAHA"

    def call_by_5g(self):
        print("子类的5g通话")
        print(f"子类:{phones.producer}")
        phones.call_by_5g(self)
        print(f"子类:{super().producer}")
        super().call_by_5g()


phone = MyPhone()
phone.call_by_5g()
print(phone.producer)
# 运行结果:
# 子类的5g通话
# 子类:RAY
# 父类的5g通话
# 子类:RAY
# 父类的5g通话
# HAHA

六、类型注解

类型注解:在代码中涉及数据交互的地方,提供数据类型的注解(显式的说明)

主要功能:

  • 帮助第三方IDE对代码进行类型推断,协助做代码提示
  • 帮助开发者自身对变量进行类型注释

注意事项:

类型注解只是提示性的,并未决定性的。数据类型和注解类型无法对应也不会导致错误

1、变量的类型注解

基础语法:**变量: 类型**

py 复制代码
# 基础数据类型注解
var_1: int = 1
var_2: float = 2.222
var_3: bool = True
var_4: str = "Ray"

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

# 基础容器类型注解
my_list: list = [1, 2, 3]
my_tuple: tuple = (1, 2, 3)
my_set: set = {1, 2, 3}
my_dict: dict = {"name": "Ray"}
my_str: str = "Ray"

# 容器类型详解
mylist2: list[int] = [1, 2, 3]
my_tuple2: tuple[str, int, bool] = ("Ray", 1, True)
my_set2: set[int] = {1, 2, 3}
my_dict2: dict[str, int] = {"Ray": 666}
# 注意
# ·元组类型设置类型详细注解,需要将每一个元素都标记出来
# ·字典类型设置类型纤细注解,需要2个类型,第一个是Key,第二个是Value

2、函数(方法)的类型注解

基础语法:

python 复制代码
def 函数方法名(形参名:类型,形参名:类型,......):
    pass
python 复制代码
# 调用示例
def add(a: int, b: int):
    return a + b

同时,函数(方法)的返回值也是可以添加类型注解的

语法:

python 复制代码
def 函数方法名(形参名:类型,形参名:类型,......)->返回值类型:
    pass
python 复制代码
# 调用示例
def func(data: list) -> list:
    return data

3、Union类型

使用Union可以定义联合类型注解

使用Union类型,必须先导包

python 复制代码
from typing import Union

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

def func(data: Union[int, str]) -> Union[int, str]:
    pass

七、多态

多态,指的是:多种状态,即完成某种行为时,使用不同的对象会得到不同的状态。

多态常作用在继承关系上

比如

  • 函数(方法)形参声明接收父类对象
  • 实际传入父类的子类对象进行工作

即:

  • 以父类做定义声明
  • 以子类做实际工作
  • 用以获得同一行为,不同状态
python 复制代码
class Animal:
    def speak(self):
        pass
class Dog(Animal):
    def speak(self):
        print("Woof!")
class Cat(Animal):
    def speak(self):
        print("Wow!")
dog = Dog()
cat = Cat()
dog.speak()
cat.speak()

抽象类

包括抽象方法的类,称之为抽象类

抽象方法指的是:没有具体实现的方法(pass)称之为抽象方法

抽象类的作用

多用于顶层设计(设计标准),以便子类做具体实现

也是对子类的一种软性约束,要求子类必须复写(实现)父类的一些方法

并配合多态使用,获得不同的工作状态

相关推荐
才不做选择1 天前
基于 YOLOv8 的部落冲突 (Clash of Clans) 目标检测系统
人工智能·python·yolo·目标检测
龘龍龙1 天前
Python基础学习(十一)
python·学习·mysql
a努力。1 天前
京东Java面试被问:双亲委派模型被破坏的场景和原理
java·开发语言·后端·python·面试·linq
程序员小远1 天前
UI自动化测试框架:PO模式+数据驱动
自动化测试·软件测试·python·selenium·测试工具·职场和发展·测试用例
2501_941805311 天前
从微服务网关到统一安全治理的互联网工程语法实践与多语言探索
前端·python·算法
Chris_12191 天前
Halcon学习笔记-Day5
人工智能·笔记·python·学习·机器学习·halcon
2501_941800881 天前
从微服务限流到系统稳定性的互联网工程语法实践与多语言探索
开发语言·python
GalenZhang8881 天前
使用 Python SDK 将数据写入飞书多维表格
数据库·python·飞书·多维表格
清水白石0081 天前
《深度剖析 Pandas GroupBy:底层实现机制与性能瓶颈全景解析》
开发语言·python·numpy