Python | 第十二章 | 继承 | 重写 | 类型注解 | 多态

P120 继承快速入门 2025/2/15

一、为什么需要继承

image-20250215161317002

  • 老方法

image-20250215161615163

  • 问题的分析
  1. pupil 和 graduate有很多相同的属性和方法
  2. 目前这样的做法,代码复用性差
  3. 同时也不利于代码的维护和管理
  4. 引出—>继承

二、基本介绍

  • 继承介绍

    1. 继承可以解决代码复用,让我们的编程更加靠近人类思维
    2. 当多个类存在相同的属性(成员变量)和方法时,可以从这些类中**抽象出父类,**在父类中定义这些相同的属性和方法,所有的子类不需要重新定义这些属性和方法。
  • 继承示意图

image-20250215162831003

  • 继承基本语法
class DerivedClassName(BaseClassName):
<statement-1>
·
·
·
<statement-N>
  • 解读:
    1. 派生类就会自动拥有基类定义的属性和方法
    2. 基类习惯上也叫父类
    3. 派生类习惯上也叫子类

三、快速入门

  • 使用继承编写的代码
# @Author :ZH_JC
# @File   :04_why_inheritance.py
# @Time   :2025/2/15 16:19

# 使用继承的代码
# 编写父类Student
class Student:
    name = None
    age = None
    __score = None

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

    def show_info(self):
        print(f"name={self.name} age={self.age} score={self.__score}")

    def set_score(self, score):
        self.__score = score


# 子类只保存特有的方法:
# 小学生类: 继承Student
class Pupil(Student):
    def testing(self):
        print("...小学生在考小学数学...")

# 大学生类: 继承Student
class Graduate(Student):
    def testing(self):
        print("...大学生在考高等数学...")


# 测试
student1 = Pupil("apple", 10)
student1.testing()
student1.set_score(70)
student1.show_info()
print("------------------")
student2 = Graduate("grape", 22)
student2.testing()
student2.set_score(80)
student2.show_info()
  • 小结:继承给编程带来的便利:
  1. 代码的复用性提高了
  2. 代码的扩展性和维护性提高了

P121 继承注意事项和细节 2025/2/15

一、注意事项和细节

  1. 子类继承了所有的属性和方法,非私有的属性和方法可以在子类直接访问,但是私有属性和方法不能在子类直接访问,要通过父类提供公共的方法去访问
# @Author :ZH_JC
# @File   :06_inheritance_detail.py
# @Time   :2025/2/15 19:29

class Base:
    # 公共属性
    n1 = 100
    # 私有属性
    __n2 = 200

    def __init__(self):
        print("Base 构造方法....")

    def hi(self):
        print("hi() 公共方法")

    def __hello(self):
        print("__hello()私有方法")

    # 提供公共方法,可以访问私有属性和方法
    def test(self):
        print("属性:",self.n1, self.__n2)
        self.__hello()

class Sub(Base):

    # 子类的构造器
    def __init__(self):
        print("Sub 构造方法....")

    def say_ok(self):
        #我们发现父类的非私有属性和方法可以访问
        print("say_ok()",self.n1)
        self.hi()  # hi()公共方法

        #我们发现父类的私有属性和方法不可以访问
        # print(self.__n2)  # 不会成功
        # self.__hello() # 方法同样报错

# 创建子类对象
sub = Sub()
sub.say_ok()

# 调用子类继承父类的公共方法去实现访问父类的私有成员效果
sub.test() # 属性: 100 200  __hello()私有方法
  • 图中可以看出子类是继承于父类的:

image-20250215194802328

  1. Python编程语言中,"object"是所有其它类的基类

image-20250215195136216

  1. Python支持多重继承
# 继承多个基类的定义语句:
class DerivedClassName(Base1,Base2,Base3...):
<statement-1>


<statement-N>

代码演示

class A:
    n1 = 100
    def sing(self):
        print("A sing()...",self.n1)


class B:
    n2 = 200
    def dance(self):
        print("B dance()...",self.n2)

# C类继承了A和B类:
class C(A, B):
    # Python pass 是空语句,是为了保持程序结构的完整性
    # pass 不做任何事情,一般用做占位语句
    pass

c = C()
print("----------------")

# 继承的属性信息
print(f"属性信息 {c.n1} {c.n2}")
# 调用继承的方法
c.dance()
c.sing()

image-20250215195733721

  • 同样可以看到C的n1来自于A,n2来自于B

image-20250215195942446

  1. 在多重继承中,如果有同名的成员,遵守从左到右的继承优先权(即:写左边的父类优先级高,写在右边的父类优先级低)
class DerivedClassName(Base1,Base2,Base3...): # 优先base1
  • 代码演示
class A:
    n1 = 100

class B:
    n2 = 200
    n1 = 300
    
class C(B, A):  # 取决于A,B左右的排列
    pass

c = C()
print("----------------")

print(f"属性信息 {c.n1} {c.n2}")

P122 继承课堂练习 2025/2/17

一、练习题

  1. 以下代码输出?
# @Author :ZH_JC
# @File   :07_inheritance_exercise.py
# @Time   :2025/2/17 11:20

class GrandPa:

    name = "大头爷爷"
    hobby = "旅游"

class Father(GrandPa):
    name = "大头爸爸"
    age = 39

class Son(Father):
    name = "大头儿子"

son = Son()

# 如果在本类没有找到就在父类去找,父类没有就在父类的父类去找
print(f"son.name={son.name} son.age={son.age} son.hobby={son.hobby}") 

image-20250217112724710

  1. 编程题:
  • 编写Computer类,包含CPU、内存、硬盘等属性
  1. get_details方法用于返回Computer的详细信息
  2. 编写PC子类,继承Computer类,添加特有属性【品牌brand】
  3. 编写NotePad子类,继承Computer类,添加特有属性【color】
  4. 完成测试,创建PC和NotePad对象,分别给对象中特有的属性赋值,以及从Computer类继承的属性赋值,并使用方法打印输出信息。
 # @Author :ZH_JC
# @File   :08_inheritance_exercise08.py
# @Time   :2025/2/17 11:30

# * 编写Computer类,包含CPU、内存、硬盘等属性

# 1) get_details方法用于返回Computer的详细信息
# 2) 编写PC子类,继承Computer类,添加特有属性【品牌brand】
# 3) 编写NotePad子类,继承Computer类,添加特有属性【color】
# 4) 完成测试,创建PC和NotePad对象,分别给对象中特有的属性赋值,以及从Computer类继承的属性赋值,并使用方法打印输出信息。

"""
    思路分析:
    1. 父类:Computer
    2. 公共属性:CPU(cpu), 内存(memory), 硬盘(disk)
    3. 构造器(这里没有set设置属性,所以需要构造器):__init__(self, cpu, memory, disk)
    4. 方法: get_details(self)
    5. 子类:PC
    6. 公共属性 brand
    7. 构造器:__init__(self,cpu, memory, disk,brand) 父类继承的属性同样需要传入
    8. 方法:print_info(self) 完成功能: 输出对象的信息(即属性的信息)
"""

class Computer:
    cpu = None
    memory = None
    disk = None

    def __init__(self,cpu,memory,disk):
        self.cpu = cpu
        self.memory = memory
        self.disk = disk

    def get_details(self):
        return f"详细信息:cpu:{self.cpu} memory:{self.memory} disk:{self.disk}"

class PC(Computer):
    brand = None

    def __init__(self,cpu,memory,disk,brand):
        # 1. 初始化子类的属性-方式1
        self.cpu = cpu
        self.memory = memory
        self.disk = disk
        self.brand = brand


        # 2. 初始化子类的属性-方式2
        # 在子类的构造器可以调用父类的构造器是可以的
        """
               解读: super().__init__(cpu,memory,disk)
               1. 通过super().xx的方式可以调用父类的方法
               2. 这里我们就通过 super().__init__(cpu,memory,disk)去调用父类构造器
                  完成对父类属性的初始化任务(相当于把父类初始化的任务就交给父类的构造器去完成)
               3. self.brand = brand 表示子类特有的属性,由子类构造器完成初始化
        """
        super().__init__(cpu,memory,disk)
        self.brand = brand 

    def print_info(self):
        """
        完成当前子类的当前信息
        """
        # 后面父类的属性可以通过在子类调用父类的方法进行输出
        print(f"品牌:{self.brand} {self.get_details()}")


class Notepad(Computer):
    pass

# 可以在这里下断点进行调试,查看详细过程
pc = PC("inter",32,1000,"戴尔")

pc.print_info()

image-20250217120503848

image-20250217120533513

P123 调用父类成员细节 2025/2/17

一、基本介绍

  • 出现重名的时候,子类是不能使用self调用父类

  • 如果子类和父类出现同名的成员,可以通过父类名、super()访问父类的成员

  • 基本语法

    1. 访问父类成员1
    -访问成员变量:父类名.成员变量
    -访问成员方法:父类名.成员方法(self)
    
    1. 访问父类成员2
    访问成员变量:super().成员变量
    访问成员方法:super().成员方法()
    
    • 代码展示
# @Author :ZH_JC
# @File   :09_访问父类成员.py
# @Time   :2025/2/17 19:22

# 通过父类名访问父类成员的形式

class A:
    n1 = 100

    def run(self):
        print("A-run()....")


class B(A):
    # n1 = 200

    def run(self):
        print("B-run()....")

    # say方法: 通过父类名访问父类成员
    def say(self):
                                    # self.n1会现在本类找
        print(f"父类的n1 {A.n1} 本类的n1 {self.n1}") # 100 200
        # 调用父类的run
        A.run(self)
        # 调用本类的run
        self.run()

    # hi方法:通过super()方式去访问父类成员
    def hi(self):
        # 直接调用的是一级父类,直接父类
        print(f"父类的n1 {super().n1}")
        # 调用父类的run
        super().run()

b = B()
# b.say()
b.hi()

二、注意事项和细节

  1. 子类不能直接访问父类的私有成员
# @Author :ZH_JC
# @File   :10_访问父类成员细节.py
# @Time   :2025/2/17 19:38


class A:
    n1=100
    __n2=600

    def run(self):
        print("A-run()....")

    def __jump(self):
        print("A-jump()....")

class B(A):
    def say(self):

        # # 子类不能直接访问父类的私有成员和方法
        # print(A.__n2)
        # print(super().__n2)

        A.__jump(self)
        super().__jump()
        print("say()....")


b=B()
b.say()
  1. 访问不限于直接父类,而是建立从子类向上级父类的査找关系 A->B->C…
class Base:
    n3=800
    def fly(self):
        print("Base-fly()...")

class A(Base):
    n1=100
    __n2= 600

    def run(self):
        print("A-run()....")
    def jump(self):
        print("A-jump()....")

class B(A):
    def say(self):
        print("say()...")

        # 访问不限于直按父类,而是建立从子类向上级类的查找关系A->B->Base...
        # Base.n3:表示直接访问Base类的n3属性--->800
        # A.n3 : 表示直接访问A类的n3--->800
        # suepr().n3: 表示从B类的直接父类去访问n3 -->800
        print(Base.n3, A.n3, super().n3)

        # 这里一定要带self,因为前面的对象是类名,而不是对象名

        Base.fly(self) # 直接访问Base的fly
        A.fly(self)  # 直接访问A的fly
        super().fly() # 直接调用当前类的直接父类A
        self.fly() # 调用本类B的方法


b = B()
b.say()
  1. 建议使用super()的方式,因为如果使用父类名方式,一旦父类变化,类名需要统一修改,比较麻烦。

P124 调用父类成员练习题 2025/2/18

一、练习题

  1. 分析下面的代码,看看输出什么内容?
# @Author :ZH_JC
# @File   :11_super_exercise.py
# @Time   :2025/2/19 18:38

class A:
    n1 = 300
    n2 = 500
    n3 = 600

    def fly(self):
        print("A-fly()...")


class B(A):
    n1 = 200
    n2 = 400

    def fly(self):
        print("B-fly()...")


class C(B):
    n1 = 100

    def fly(self):
        print("C-fly()...")

    def say(self):
        print(self.n1) # 100
        print(self.n2) # 400
        print(self.n3) # 600
        print(super().n1) # 200
        print(B.n1) # 200
        print(C.n1) # 100

c = C()
c.say()
  1. 针对上面的程序,想在C的say()中,调用C的fly()和 A的fly(),应该如何调用?
        # 想在C的say()中,调用C的fly()和A的fly(),应该如何调用?
        self.fly()  # C-fly
        A.fly(self) # A-fly
        super().fly() # B-fly (如果B类中没有fly,则可以调用到A的fly)

P125 重写Override 2025/2/20

一、基本介绍

  • 重写又称覆盖(override),即子类继承父类的属性和方法后,根据业务需要,再重新定义同名的属性或方法

image-20250220121411128

二、编程题

  • 编程题:
    • 编写一个Person类,包括属性(name、age),构造方法、say方法(返回Person自我介绍的字符串)
    • 编写一个Student类,继承Person类,增加属性(id、score),以及构造方法,重写say方法(返回Student自我介绍的信息)
    • 分别创建Person和Student对象,调用say方法输出自我介绍,体会重写的作用
# @Author :ZH_JC
# @File   :12_override_exercise.py
# @Time   :2025/2/20 12:16
class Person:
    name = None
    age = None

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

    def say(self):
        return f"名字:{self.name} 年龄:{self.age}"


class Student(Person):
    id = None
    score = None

    def __init__(self, name, age, id, score):
        # 调用父类构造器
        super().__init__(name, age)
        # 子类属性自己完成
        self.id = id
        self.score = score

    def say(self):
        # suepr().say()调用父类的方法
        return f"{super().say()} ID:{self.id} 成绩:{self.score}"


person = Person("张三", 18)
student = Student("李四", 22, 2, 90)

print(person.say())
print(student.say())

image-20250220124111690

P126 类型注解介绍 2025/2/20

  • 参考文档:https://docs.python.org/zh-cn/3.12/glossary.html#glossary

image-20250220133307747

一、基本介绍

  • 为什么需要类型注解:

  • 随着项目越来越大,代码也就会越来越多,在这种情况下,如果没有类型注解,很容易不记得某一个方法的参数类型是什么。

  • 一旦传入了错误类型的参数,python是解释性语言,只有运行时候才能发现问题,这对大型项目来说是一个巨大的灾难

  • 代码案例

#对字符串进行遍历
def fun1(a):
    for ele in a:
        print(ele)

# ctr+p 提示参数时,没有类型提示
# 如果类型传错了,就会出现异常,比如传的是整型
fun1(100)

二、类型注解作用和说明

  • 自python3.5开始,引入了类型注解机制,作用和说明如下:
  1. 类型提示,防止运行时出现参数类型、返回值类型、变量类型不符合。
  2. 作为开发文档附加说明,方便使用者调用时传入和返回参数类型
  3. 加入后并不会影响程序的运行,不会报正式的错误,只有提醒
  4. PyCharm支持类型注解,参数类型错误会黄色提示

image-20250220135101951

image-20250220135136920

# a:str : 给形参a进行类型注解,标注形参a的类型是str
def fun1(a: str):

P127 类型注解使用 2025/2/20

一、类型注解

基本语法:

  • 变量:类型
"""
    解读:
    1. n1:int : 对n1进行类型注解,标注n1的类型为int
    2. 如果给出值的类型和标注的类型不一致,则pycharm会给出黄色警告

"""
n1:int= 10
n2: float = 10.1
is_pass: bool = True
name: str="燕赤霞"
  • 实例对象类型注解
class Cat:
    pass

#实例对象类型注解
# cat: Cat :对cat进行类型注解,标注cat的类型时Cat
cat: Cat = Cat()

image-20250220144857284

  • 容器变量注解
#容器类型注解
"""
      解读:
     1. my_list:对my_list进行类型注解,标注my_list的类型时list
     2...
"""
my_list: list =[100, 200, 300]
my_tuple: tuple = ("run", "sing", "fly")
my_set: set = {"jack", "tim", "hsp"}
my_dict: dict = {"no1":"北京","no2":"上海"}
  • 容器详细类型注解
# 容器详细类型注解
"""
   1. my_list2:list[int] 对my_list2进行类型注解:
      标注my_list2类型是list,而且该list元素是int
"""
my_list2:list[int]=[100,200,300]

# 元组类型设置详细类型注解,需要把每个元素类型都标注一下
my_tuple2:tuple[str,str, str,float]=("run","sing","fly",1.1)

my_set2:set[str]= {"jack","tim","hsp"}

# 字典类型设置详细类型注解,需要设置两个类型,即[key类型,value类型
# my_dict2:dict[str,int] 标注my_dict2是字典类型,key的类型时str,值的类型时int
my_dict2:dict[str,int]={"no1":100,"no2":200}
  • 在注释中使用注解
# 注释中使用注解
# 解读 # type: float 用于标注 变量n3 的类型是 float

n3 = 89.0 # type: float
my_list3=[100,200,300] # type: list[int]
email = "hsp@sohu.com" # type: str
  • 函数(方法)中的类型注解

基本语法

def 函数/方法名(形参名:类型,形参名:类型 ....)-> 返回值类型:
    函数/方法体

案例

"""
    解读:
    1. name:str 对形参name进行类型注解:标注name类型时str
    2. 在调用方法/函数时,传入的实参类型不是一样的,则给出黄色的警告
"""

def fun1(name: str):
    for ele in name:
        print(ele)

fun1("zjc")


# 接收两个整数,返回整数
"""
    分析:
    1. a: int, b: int 对形参a和b进行类型注解,-> int对返回值进行类型注解
"""
def fun2(a: int, b: int) -> int:
    return a + b

print(f"结果是:{fun2(10, 20)}")

二、说明

  • 类型注解是提示性的,并不是强制性的,如果你给的类型和指定/标注的类型不一致,PyCharm 检测到会给出黄色警告,但是仍然可以运行

三、union类型

  • 参考文档:https://docs.python.org/zh-cn/3.12/library/typing.html#typing.Union

image-20250220152637445

  • 基本介绍
  1. Union类型可以定义联合类型注解
  2. 在变量、函数(方法)都可以使用Union联合类型注解
  3. 使用的时候,需要先导入Union:from typing import Union
  • 基本语法

Union[类型,类型…]
比如:联合类型:Union[X,Y,Z,.] 等价于 X|Y ,意味着满足 X 或Y之一

  • 代码演示
# @Author :ZH_JC
# @File   :16_union_type_hint.py
# @Time   :2025/2/20 15:34

# 如果要使用union联合注解,则需要导入union
from typing import Union

# 联合类型注解,a 可以是int或者str
a: Union[int, str] = 100

# my list是list类型,元素可以是int或者str
my_list: list[Union[int, str]] = [100, 200, 300, "tim"]


# 函数方法使用联合类型注解
# 接收两个数(可以是int/float),返回数(int/float)
def cal(num1: Union[int, float],
        num2: Union[int, float]) -> Union[int, float]:
    return num1 + num2

print(f"结果是: {cal(10, 20.2)}")

P128 多态问题引出 2025/2/21

一、问题引出

image-20250221115605804

  • 代码展示
# @Author :ZH_JC
# @File   :17_master_feed_animal.py
# @Time   :2025/2/21 11:56

# 先使用传统的方式写

class Food:
    name = None

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


class Fish(Food):
    # 特有属性和方法
    pass

class Bone(Food):
    # 特有属性和方法
    pass

class Animal:

    name = None

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

class Dog(Animal):
    pass

class Cat(Animal):
    pass

class Master:
    name = None

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

    # 给猫猫喂鱼
    def feed_cat(self, cat:Cat, fish:Fish):
        print(f"主人:{self.name} 给动物:{cat.name} 喂的食物是:{fish.name}")

    # 给狗狗喂骨头
    def feed_dog(self, dog:Dog, bone:Bone):
        print(f"主人:{self.name} 给动物:{dog.name} 喂的食物是:{bone.name}")


# 测试
master = Master("老韩")
cat = Cat("小花猫")
fish = Fish("黄花鱼")
dog = Dog("大黄狗")
bone = Bone("大棒骨")

master.feed_cat(cat,fish)
master.feed_dog(dog,bone)

# 问题分析:如果动物/食物种类很多,怎么办?

image-20250221121357849

  • 问题分析
    • 问题分析:如果动物/食物种类很多,怎么办?
  1. 问题是:代码的复用性不高,而且不利于代码维护和功能扩展
  2. 解决方案:引出我们要讲解的多态

P129 多态继承和使用 2025/2/21

一、多态介绍

  • 怎么理解多态
    • 多态顾名思义即 多种状态,不同的对象调用相同的方法,表现出不同的状态,称为多态。
    • 多态通常作用在继承关系上(后面有特别说明)
  • 解读
    • 举例说明:一个父类,具有多个子类,不同的子类对象调用相同的方法,执行的时候产生不同的状态,就是多态
# @Author :ZH_JC
# @File   :18_poly_examply.py
# @Time   :2025/2/21 13:02

class Animal:
    def cry(self):
        pass

class Cat(Animal):
    def cry(self):
        print("小猫 喵喵叫...")


class Dog(Animal):
    def cry(self):
        print("小狗 汪汪叫...")

class Pig(Animal):
    def cry(self):
        print('小猪 噜噜叫...')

# 注意:1. 在python面向对象编程中,子类类型可以传递给父类类型;如果给的类没有相应的继承关系,则会有警告
def func(animal: Animal):
    # 这里传入的类型其实是cat
    print(f"animal 类型是{type(animal)}")
    # 这里就调用相同的方法,但执行的时候会产生不同的状态
    animal.cry() # 这里调用理应也是cat类,如果cat类没有,才会去父类查找


# 创建三个对象:
cat = Cat()
dog = Dog()
pig = Pig()

# 调用函数
func(cat)
func(dog)
func(pig)
  • 多态的好处
    • 增加了程序的灵活性,以不变应万变,不论对象千变万化,使用者都是同一种形式去调用,如func(animal),代码说明
    • 增加了程序的可扩展性,通过继承Animal类创建了一个新的类,使用者无需更改自己的代码,还是用func(animal)去调用
# 这里不需要改变父类的代码或者其他类,扩展性强
class Bird(Animal):
    def cry(self):
        print("小鸟 喳喳叫...")
  • 特别说明python的多态特点
    • Python中函数/方法的参数是没有类型限制的,所以多态在python中的体现并不是很严谨(比如:和java等强类型语言比)
    • Python并不要求严格的继承体系,关注的不是对象的类型本身,而是它是否具有要调用的方法(行为)
class AA:
    def hi(self):
        print("AA-hi()...")

class BB:
    def hi(self):
        print("BB-hi()...")

 # 这里没有类型注解,不管你是什么类型,只关注是否有调动的方法
def test(obj):
    obj.hi()

aa = AA()
bb = BB()
test(aa)
test(bb)

二、二说主人喂动物问题

  • 代码优化
class Master:
    name = None

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

	def feed(self, animal:Animal,food:Food):
        print(f"主人:{self.name} 给动物:{animal.name} 喂的食物是:{food.name}")

# 测试
master = Master("老韩")
cat = Cat("小花猫")
fish = Fish("黄花鱼")
dog = Dog("大黄狗")
bone = Bone("大棒骨")

master.feed(cat,fish)
master.feed(dog,bone)
  • 可以扩展一下 Horse,Grass,体会多态的机制 带来的好处
# @Author :ZH_JC
# @File   :17_master_feed_animal.py
# @Time   :2025/2/21 11:56
from doctest import master


# 使用多态特性来优化:

class Food:
    name = None

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

class Fish(Food):
    # 特有属性和方法
    pass

class Bone(Food):
    # 特有属性和方法
    pass

class Grass(Food):
    pass

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

class Dog(Animal):
    pass

class Cat(Animal):
    pass

class Horse(Animal):
    pass

class Master:
    name = None

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

    # 主人给动物喂食物:(多态)
    def feed(self, animal:Animal,food:Food):
        print(f"主人:{self.name} 给动物:{animal.name} 喂的食物是:{food.name}")

# 测试
master = Master("老韩")
cat = Cat("小花猫")
fish = Fish("黄花鱼")
dog = Dog("大黄狗")
bone = Bone("大棒骨")
horse = Horse("枣红马")
grass = Grass("嫩草")

master.feed(cat,fish)
master.feed(dog,bone)
master.feed(horse,grass)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

一颗星星辰

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值