2023年7月21日星期五

py oop

myobject

使用对象组织数据

在程序中是可以做到和生活中那样,设计表格、生产表格、填写表格的组织形式的

  1. 在程序中设计表格,我们称之为:
    设计类 (class)
class Student:
name = None # 记录学生姓名。这里none是初始化值

2.在程序中打印生产表格,我们称之为: 创建对象

#基于类创建对象
stu_1 = Student
stu_2 = Student()

3.在程序中填写表格,我们称之为:
对象属性赋值

stu_1.name =“周杰轮"#为学生1对象赋予名称属性值
stu_2.name = “林军杰"#为学生2对象赋予名称属性值
  1. 方法调用自身成员,需要在参数列表中添加形参self

构造方法

Python类可以使用:
__init__()方法,称之为构造方法。
可以实现:
在创建类对象(构造类)的时候,会自动执行
在创建类对象(构造类)的时候,将传入参数自动传递给 __init__ 方法使用

class Student:
    name = None

    def __init__(self,name):
        self.name = name
        print("创建了一个Student对象")
    def printSelf(self):
        print(f"我是{self.name}")

stu1 = Student("小希")

同时需要自带self

其他常见类内置方法

又叫魔术方法

__init__构造方法

_str_ 字符串方法

class student:
def __init__(self,name, age):
se7f.name = name
self.age = age
student = student("周杰轮"11)
print(student)# 结果:< main__.student object at 0x000002200CFD7040>
print(str(student)) # 结果:<main.student obiect at 0x000002200CFD7040>

当类对象需要被转换为字符串之时,会输出如上结果 (内存地址)
内存地址没有多大作用,我们可以通过重载__str__方法,控制类转换为字符串的行为

class Student:
    name = None
    age = None

    def __init__(self, name: "str", age: "int"):
        self.name = name
        self.age = age

    def __str__(self) -> str:
        return f"这是Student对象,name成员{self.name},age成员{self.age}"


stu1 = Student("reimu", 24)
print(str(stu1))

_lt_ 小于符号,大于符号比较

实则重载小于符号为true时的规律,如

class Student:
    age = None
    name = "223"

    def __init__(self, age) -> None:
        self.age = age

    def __lt__(self, other: "Student"):
        return self.age < other.age


print(Student(20) < Student(15))

_le_ 小于等于,大于等于符号比较

= <= 规则类似于__lt__

_eq_ ==符号比较

规则也类似__lt__,但规则默认是判断内存地址是否相等

面向对象OOP

基于模板(类)去创建实体(对象),使用对象完成功能开发
三大特性:封装,继承,多态

封装

image.png

私有成员

不公开的属性和行为
变量和方法只需以两个下划线开头即可
类外访问成员不报错,无效。访问方法报错。
和c++相同,可以被其他的成员使用

实际意义

在类中提供仅供内部使用的属性和方法
而不对外开放(类对象无法使用 )

继承

概念,使用方式,pass关键字

class 类名(父类名):
    类内容体 

继承分为单继承和多继承
多继承,继承多个父类

class Xiaomi(Phone,NFCreader,RemoteControl):
    pass

多个父类中,如果有同名的成员,那么默认以继承顺序(从左到右)为优先级
先继承的保留,后继承的被覆盖
比如Phone的producer成员是"Huawei"
NFCreader的producer成员是"Samsung"
那么最终Xiaomi的producer是"Huawei"

复写和使用父类成员

子类继承父类成员和方法后,不满意可进行复写
在子类中重新定义同名的属性和方法即可
(属性的是初始化的量)

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

  1. 直接调用父类成员
    • 使用成员变量:父类名.成员变量
    • 使用成员方法:父类名.成员方法(self)
  2. 使用**super()**调用父类成员
    • 使用成员变量:super().成员变量
    • 使用成员方法:super().成员方法()

变量的类型注解

为什么需要:定义函数中的类型方法自动补齐

# 例如这里,虽然心中所想data是list类型,但是不会补齐
def func(data):
    data.app^

用处:标注数据类型

  1. 变量的类型注解
  2. 函数(方法)形参列表和返回值的类型

基础语法:
变量:类型

var_1:int = 10
var_2:bool = False
# 类对象:
class Student:
    pass
stu:Student = Student()
# 基础容器类型注解
my_list:list = [1,2,3]
my_dict:dict = {"it":23}
# 容器类型详细注解
my_list:list[int] = [1,2,3]
my_tuple:tuple[str,int,bool] = ('it',666,True)
my_set:set[int] = {1,2,3}
my_dict:dict[str,int] = {'it':666}
'''
注意:
元组类型设置类型详细注解,需要将每一个元素都标记出来
字典类型设置类型详细注解,需要2个类型,第一个是key第二个是value
'''

# 另外可以通过注释进行类型注解
# 语法: #type:类型
var_1 = random.randint(1,10) # type: int

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

形参注解

def func(data:list):
    pass

返回值进行类型注解

def func(data:list)->list:
    return data
    pass

但如果语法没有问题的话,其实你传个1其实不会error只会warning

union类型

# 类型统一
my_list:list[int] = [1,2,3]
my_dict:dict[str,int] = {"age":11, "num":3}
# 如何描述混合类型?
my_list = {1, 2, "itcast", "itheima"}
my_dict = {"name":"周", "age":31}
# 使用union[类型,类型...] 
my_list = {1, 2, "itcast", "itheima"}
my_dict = {"name":"周", "age":31}

多态

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

# 复写
class Anima1:
    def speak(se1f):
    pass
class Dog(Anima1):
    def speak(se1f):
        print("汪汪汪")
class cat(Animal):
    def speak(se1f) :
        print("喵喵喵")
def make_noise(animal: Animal) : # 子类继承Animal类,故有speak()方法不会报错
    animal.speak()
dog = Dog()
cat = cat()
make_noise(dog)# 输出: 汪汪汪
make_noise(cat)# 输出: 喵喵喵

子类dog父类animal子类catdefmake_noise(animal:Animal);子类 \begin{aligned} &\to子类\text{dog}\\ 父类\text{animal} &\rightarrow 子类\text{cat}\Rightarrow def\quad make\_noise(animal:Animal); \\ &\to 子类\dots \end{aligned}

多态常作用在继承关系上
比如

  • 函数(方法)形参声明接收父类对象
  • 实际传入父类的子类对象进行工作
    即:
  • 以父类做定义声明
  • 以子类做实际工作
  • 用以获得同一行为,不同状态

这里Animal的speak方法是空实现,设计含义是

  • 父类用来确定有哪些方法
  • 具体的方法实现,由子类自行决定
    这种写法,就叫做抽象类(也可以称之为接口)
  • 抽象类:含有抽象方法的类称之为抽象类
  • 抽象方法:方法体是空实现的(pass)称之为抽象方法
    抽象类好比一个标准,顶层设计,要求子类必须实现

0 评论:

发表评论