python -【八】面向对象

一、类

类的定于语法:

class 类名称:

类属性(字段)

类行为(函数)

创建类对象的语法:

对象 = 类名称()

python 复制代码
"""
学生类
"""
import json


# 定义一个学生类
class Student:
    name = None  			# 姓名
    gender = None  			# 性别
    nationality = None  	# 国籍
    native_place = None  	# 籍贯
    age = None  			# 年龄


# 创建一个对象
stu = Student()
stu.name = '张三'
stu.gender = '男'
stu.nationality = '中国'
stu.native_place = '北京'
stu.age = 30

# 获取对象内的信息
stu_str = json.dumps(stu.__dict__, ensure_ascii=False)
print(stu_str)

1.1 类的成员方法

python 复制代码
class Student:
    name = None  			# 姓名
    gender = None  			# 性别
    nationality = None  	# 国籍
    native_place = None  	# 籍贯
    age = None  			# 年龄

    # 无参方法
    def say_hi(self):
        print(f'Hi, 我是{self.name}')

    # 有参方法
    def say(self, msg):
        print(f'大家好,我叫{self.name},{msg}')
        

stu = Student()
stu.name = '坤坤'
stu.gender = '男'
stu.nationality = '中国'
stu.native_place = '北京'
stu.age = 30
# 调用类方法
stu.say_hi()
stu.say('我喜欢,唱,跳,rap,篮球')

1.2 构造方法

类的构造方法作用:

  1. 创建类对象的时候,构造方法会自动执行
  2. 创建类对象的时候,将传入参数自动传递给 __init__ 方法使用
python 复制代码
class Student:
    # 构造函数内声明成员变量,不需要再定义成员变量
    def __init__(self, name, age, tel):
        self.name = name
        self.age = age
        self.tel = tel

    def print_info(self):
        print(f'姓名:{self.name}, 年龄:{self.age},电话:{self.tel}')


s = Student('张三', 19, '12345678910')
s.print_info()
s1 = Student('李四', 22, '12345678911')
s1.print_info()

1.3 练习题

开学了有一批学生信息需要录入系统,请设计一个类,记录学生的:姓名、年龄、地址,这3类信息

请实现:

  • 通过for循环,配合input输入语句,并使用构造方法,完成学生信息的键盘录入
  • 使用print语句,完成信息的输出
python 复制代码
class Stud:

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

    # 打印学生的信息
    def print_info(self):
        print(f'学生信息{self.idx}录入完成,信息为【姓名:{self.name},'
              f' 年龄:{self.age},地址:{self.address}】')


# 输入学生的信息
def trigger():
    for i in range(1, 3):
        name = input('请输入学生姓名:')
        age = input('请输入学生年龄:')
        address = input('请输入学生地址:')
        stud = Stud(i, name, age, address)
        stud.print_info()


if __name__ == '__main__':
    trigger()

1.4 魔术方法(内置方法)

上文中 __init__ 方法就是 python 内置方法之一,这些内置方法各自有各自的特殊功能,统称为:魔术方法

  • __init__ 构造方法
  • __str__ 字符串方法
  • __lt__ 小于,大于符号比较
  • __le__ 小于等于,大于等于符号比较
  • __eq__ == 比较符号
python 复制代码
class Student:
    def __init__(self, name, age):
        self.name = name
        self.age = age

    # 对象的 tostring 方法
    def __str__(self):
        return f'对象to string, name:{self.name}, age:{self.age}'

    # 比较函数定义
    def __lt__(self, other):
        return self.age < other.age

    # 小于等于
    def __le__(self, other):
        return self.age <= other.age

    # equals 方法,不实现则是比较内存地址
    def __eq__(self, other):
        return (self.name == other.name
                and self.age == other.age)


st1 = Student('张三', 32)
print(f"对象1:{st1}")					# 对象1:对象to string, name:张三, age:32

st2 = Student('张三', 32)
print(f"对象2:{st2}")					# 对象2:对象to string, name:张三, age:32

print(f'st1 < st2: {st1 < st2}')	  	# st1 < st2: False
print(f'st1 <= st2: {st1 <= st2}')    	# st1 <= st2: True
print(f'st1 == st2: {st1 == st2}')    	# st1 == st2: True

二、面向对象的三大特性

2.1 封装

封装:将现实世界事物在类中描述为属性和方法,即为封装

私有的变量,方法定义规则:__ 两个下划线开头的定义为私有的

python 复制代码
"""
演示私有变量和私有方法的访问限制
"""

class Phone:
    # 私有成员
    __current_voltage = None

    # 私有方法
    def __keep_single_core(self):
        a = self.__current_voltage
        print(f'CPU以单核运行, 当前电压:{a}...')


p = Phone()
# 这里调用对象的私有方法会报错
# 'Phone' object has no attribute '__keep_single_core'. Did you mean: '_Phone__keep_single_core'?
p.__keep_single_core()
python 复制代码
"""
私有变量和私有方法的正确访问姿势
私有的函数并非是不能使用,而是在 class 外部不能使用,但是在 class 内部可以被使用

如下案例中:call_by_5g 函数调用了私有方法 __keep_single_core,实现了在 class 内部调用
"""

class Phone:
    __current_voltage = 0.5

    def __init__(self, cv):
        self.__current_voltage = cv

    def __keep_single_core(self):
        a = self.__current_voltage
        print(f'CPU以单核运行, 当前电压:{a}...')

    def call_by_5g(self):
        if self.__current_voltage > 3.5:
            print('5g通话开启')
        else:
            self.__keep_single_core()
            print('电压不足,无法开启5g,并使用单核运行 ...')


p = Phone(3)
p.call_by_5g()

综合案例

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

私有成员变量: __is_5g_enable,类型 boolTrue 表示开启 5gFalse 表示关闭 5g

私有成员方法: __check_5g() ,会判断私有成员 __is_5g_enable 的值

  • 若为True,打印输出: 5g开启
  • 若为False,打印输出: 5g关闭,使用4g网络

公开成员方法: call_by_5g(),调用它会执行

  • 调用私有成员方法: __check_5g(),判断 5g 网络状态
  • 打印输出: 正在通话中

运行结果:

  • 5g关闭,使用4g网络
  • 正在通话中
python 复制代码
class Phone:
    # True表示开启5g,False表示关闭5g
    __is_5g_enable = None

    def __init__(self, enable):
        self.__is_5g_enable = enable

    def __check_5g(self):
        if self.__is_5g_enable:
            print('5g开启')
        else:
            print('5g关闭,使用4g网络')

    def call_by_5g(self):
        self.__check_5g()
        print('正在通话中')


p = Phone(False)
p.call_by_5g()

2.2 继承

单继承

语法:class 类名(父类名):

python 复制代码
# Phone2021 2021年的手机,只支持 4g 通话
class Phone2021:
    IMEI = None
    product = None

    def __init__(self, IMEI, product):
        self.IMEI = IMEI
        self.product = product

    def call_by_4g(self):
        print(f'Phone2021 4g 通话, {self.IMEI}')


# 单继承
# Phone2022 2022年的手机,继承了2021年的手机
# 新增了人脸识别 和 5g 通话
class Phone2022(Phone2021):
    face_id = True

    def __init__(self, face_id, IMEI, product):
        super().__init__(IMEI, product)
        self.face_id = face_id

    def call_by_5g(self):
        print(f'Phone2022 支持 5g 通话:{self.face_id}')


p = Phone2022(face_id='zyred', IMEI='AKJL23KHH2', product='苹果')
p.call_by_4g()
p.call_by_5g()

多继承

语法:class 类名(父类名1,父类名2, ...):

python 复制代码
class Phone:
 IMEI = '100000'
 producer = None

 def __init__(self, IMEI, producer):
     self.IMEI = IMEI
     self.producer = producer

 def call(self):
     print(f'{self.producer}: 开始打电话')


class NFC:
 nfc_type = '第五代'
 producer = 'GM'

 def read_card(self):
     print(f'{self.nfc_type} 读卡')

 def write_card(self):
     print(f'{self.nfc_type} 写卡')


class RemoteControl:
 rc_type = '红外遥控'

 def control(self):
     print(f'{self.rc_type} 开启')


class MyPhone(Phone, NFC, RemoteControl):
 # 补全语法,不发生错误
 pass


mf = MyPhone('100000', '苹果')
mf.control()
mf.call()
mf.read_card()
mf.write_card()

# 多继承相同属性名,那个类继承在前面,哪个的优先级高
print(f'多继承相同属性名的内容:{mf.producer}') # 输出 "苹果"

重写父类的方法和成员属性

python 复制代码
class Phone:
    IMEI = '100000'
    producer = '苹果'

    def call(self):
        print(f'{self.IMEI}: 开始打电话')


class MyPhone(Phone):
    # 重写父类的属性
    producer = '华为'

    # 重写父类的 call 方法
    def call(self):
        print(f'开启单核CPU工作 ...')
        print(f'访问父类的属性:{Phone.producer}')
        # 调用父类的方法,方式1
        Phone.call(self)
        # 调用父类的方法,方式2
        super().call()
        print(f'关闭单核CPU工作 ...')


mf = MyPhone()
mf.call()


"""
开启单核CPU工作 ...
访问父类的属性:苹果
100000: 开始打电话
100000: 开始打电话
关闭单核CPU工作 ...
"""

2.3 多态

父类引用指向子类对象

python 复制代码
class Animal:
    # 定义一个没有任何实现的方法
    def speak(self):
        pass


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


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


# 定义一个方法,传入 Animal 抽象类
# 并且调用 animal 的抽象方法
def make_nise(animal: Animal):
    animal.speak()


d: Animal = Dog()
c: Animal = Cat()

make_nise(d)
make_nise(c)
python 复制代码
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 GREE_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()
    ac.hot_wind()
    ac.swing_l_r()


midea: AC = Midea_AC()
gree: AC = GREE_AC()

make_cool(midea)
make_cool(gree)

"""
美的,制冷就是爽
美的,制热就是快
美的,左右无感摆风
格力,制冷就是爽
格力,制热就是快
格力,左右无感摆风
"""
相关推荐
ydmy1 分钟前
注意力机制(个人理解)
pytorch·python·深度学习
jinanwuhuaguo2 分钟前
OpenClaw工程解剖——RAG、向量织构与“记忆宫殿”的索引拓扑学(第十三篇)
android·开发语言·人工智能·kotlin·拓扑学·openclaw
Rust研习社4 分钟前
使用 Axum 构建高性能异步 Web 服务
开发语言·前端·网络·后端·http·rust
iwhitney1 小时前
【次方量化】3分钟搞懂什么是量化策略
python
高洁012 小时前
大模型部署资源不足?轻量化部署解决方案
python·深度学习·机器学习·数据挖掘·transformer
阿里云大数据AI技术2 小时前
MaxFrame 视频帧智能分析:从视频到语义向量的端到端分布式处理
人工智能·python
淘矿人2 小时前
从0到1:用Claude启动你的第一个项目
开发语言·人工智能·git·python·github·php·pygame
cany10002 小时前
C++ -- 模板的声明和定义
开发语言·c++
澈2072 小时前
深耕进阶 Day1:C 与 C++ 核心差异 + C++ 入门基石
c语言·开发语言·c++
嘻嘻哈哈樱桃2 小时前
牛客经典101题题解集--动态规划
java·数据结构·python·算法·职场和发展·动态规划