Python面向对象
初识对象
粗略的了解
在生活中和程序中,我们都可以使用设计表格,打印表格,填写表格的形式来有效地收集信息,组织数据
进行对比:
- 设计表格:设计类
- 打印表格:创建对象
- 填写表格:对象属性赋值
定义
-
类(Class): 用来描述具有相同的属性和方法的对象的集合。它定义了该集合中每个对象所共有的属性和方法。对象是类的实例。
-
**对象:**通过类定义的数据结构实例。对象包括两个数据成员(类变量和实例变量)和方法。
类的成员方法
类是有两部风组成的:
- 类的属性:成员变量
- 类的行为:成员方法
类和成员方法的定义语法
class 类名称: 成员变量
def 成员方法(self,参数1,参数2....) 成员方法体对象 = 类名称()self的作用:
- 表示是这个类对象本身的意思
- 只有通过self,
成员方法才能访问类的成员变量 - 尽管self出现在形参列表中,但是不占参数位置,无需理会
类和对象
面向对象编程
现实世界事物可以分为两类:
- 属性
- 行为
类也可以包括属性和行为,所以用类描述现实世界是非常合适的
一般的类的属性就是成员变量,类的行为就是成员方法
类和对象的关系: 类是程序中的“设计图纸” 对象是基于“设计图纸”生产的具体实体
什么是面向对象编程: 面向对象进行编程:使用对象进行编程 就是:设计类,基于类创建对象,并且使用对象完成具体的操作
构造方法
构造方法的名称是:__int__,注意int前后有两个下划线
构造方法的作用:
- 构建类对象会自动执行
- 构建类对象的传参会传递给构造方法,借此特性可以给成员变量赋值
注意事项:
- 构造方法不要忘记self关键字(所以方法都不要忘记self关键字)
- 在构造方法内使用成员变量需要使用self
class student: def __init__(self,name,age): self.name=name self.age=age print("学生信息已收集")stud1=student("z",33)print(stud1.name)print(stud1.age)学生信息已收集z33实例:
class student: def __init__(self, name, age,address): self.name = name self.age = age self.address = addressall_students = []for i in range(10): print(f"第{i+1}名学生录入中") n = input("请输入学生的姓名: ") a = input("请输入学生的年龄: ") addr = input("请输入学生的地址: ") new_stu = student(n, a, addr) all_students.append(new_stu) print(f"第{i + 1}名信息录入成功信息为:{new_stu.name},{new_stu.age},{new_stu.address}")第1名学生录入中请输入学生的姓名: "nima"请输入学生的年龄: 20请输入学生的地址: "beijing"第1名信息录入成功信息为:"nima",20,"beijing"第2名学生录入中请输入学生的姓名:正确的做法:每来一个学生,你先用母版复印出一张新纸(Instance/对象),填好信息,然后把这张纸放进**档案袋(List/列表)**里。
其他内置方法(魔术方法)
__?__是魔术方法
__str__方法字符串方法
当类对象没有使用__str__转换成字符串时候,会输入内存地址,这是我们要使用字符串魔术方法
class student: def __init__(self, name, age,): self.name = name self.age = agestu1=student("阿旺",21)print(stu1)print(str(stu1))<__main__.student object at 0x000002216D5B7FD0><__main__.student object at 0x000002216D5B7FD0>class student: def __init__(self, name, age,): self.name = name self.age = age def __str__(self): return f"student类对象,姓名:{self.name},年龄:{self.age}"stu1=student("阿旺",21)print(stu1)print(str(stu1))student类对象,姓名:阿旺,年龄:21student类对象,姓名:阿旺,年龄:21__lt__小于,大于符号比较方法
当类对象没有使用__lt__直接>或<比较是不行的,如果在类中使用__lt__即可完成大于符号和小于符号的两种比较
- 方法名:
__lt__ - 传入参数other另一个类对象
- 返回值:True或者False
- 内容自行定义
class student: def __init__(self, name, age,): self.name = name self.age = age def __lt__(self, other): return self.age < other.agestu1=student("阿旺",21)stu2=student("小王",22)print(stu1<stu2)True__le__小于等于,大于等于符号比较方法
当类对象没有使用__le__直接>=或<=比较是不行的,如果在类中使用__le__即可完成大于等于符号和小于等于符号的两种比较
- 方法名:
__lt__ - 传入参数other另一个类对象
- 返回值:True或者False
- 内容自行定义
class student: def __init__(self, name, age,): self.name = name self.age = age def __le__(self, other): return self.age <=other.agestu1=student("阿旺",21)stu2=student("小王",22)print(stu1<=stu2)True__eq__等于符号比较方法
- 方法名:
__eq__ - 传入参数other另一个类对象
- 返回值:True或者False
- 内容自行定义
当类对象没有使用__eq__直接等于比较是不行的,如果在类中使用__eq__即可完成等于符号的比较
class student: def __init__(self, name, age,): self.name = name self.age = age def __eq__(self, other): return self.age==other.agestu1=student("阿旺",21)stu2=student("小王",22)print(stu1==stu2)Flase封装
封装的概念:将数据和方法组合在一起形成一个类,以保护数据,防止外部程序随意访问和修改
什么是私有成员,为什么需要私有成员:
现实事物中有部分属性和行为是不公开对使用者开放的,同样在类中描述属性和方法的时候也需要达到这个要求,就需要定义私有成员了
定义私有成员:
成员变量和成员方法的命名均以__作为开头即可
私有成员的访问限制:
- 类对象无法直接的访问私有成员
- 在类中,其他成员可以直接访问私有成员
实例:
class phone: __current_V=0 def __sigle_danhe(self): print("sigle danhe") def five_g(self): if self.__current_V>=1: print("开启5g") else: self.__sigle_danhe() print("电压不够,无法开启5g,正在开启danhe运行")phone1=phone()phone1.five_g()sigle danhe电压不够,无法开启5g,正在开启danhe运行继承的基础语法
继承: 继承就是一个类继承另外一个类的成员变量和成员方法 语法:
class 字类(父亲1[,父亲2,父亲3,父亲4....父亲N]: 类内容体子类构成的类对象:
- 有自己的成员变量和成员方法
- 使用父亲的成员变量和成员方法
单继承:一个类继承另一个类 多继承:一个类继承多个类,按照顺序从左往右一次继承 多继承中,如果父类有相同的成员变量或成员方法,那么先继承的优先级高于后继承的
class father1: name="father1" def fuqing1(self): print("fuqing1")class father2: name="father2" def fuqing2(self): print("fuqing2")class son(father1,father2): passson1=son()print(son1.name)son1.fuqing1()son1.fuqing2()father1fuqing1fuqing2pass关键字的作用:
pass是占位语句,用来确保函数(方法)或类的完整性,表示无内容空的意思(如果不想写新类不想写新内容就可以使用)
复写
复习表示: 对父类的成员变量和成员方法进行重新定义
复写的语法: 在子类重新实现同名的成员变量和成员方法
class father1: name="father" def fuc(self): print("hello")class son1(father1): name="son" def fuc(self): print("nihao")son2=son1()print(son2.name)son2.fuc()sonnihao在子类中调用父类成员
方法1:
- 调用父类变量:父类名.成员变量
- 调用父类方法:父亲名.成员方法(self)
方法2(使用super()调用父类成员):
- 调用父类变量:super().成员变量
- 调用父类方法:super().成员方法
注意:只可以在子类内部调用父类的同名成员,子类的实体类对象调用默认是调用子类复写的
类型注解
- 什么是类型注解,有什么作用?**
在代码中涉及数据交互之时,对数据类型进行显式的说明,可以帮助:
- PyCharm等开发工具对代码做类型推断协助代码提示
- 开发者自身做类型的备注
类型注解支持:
- 变量的类型注解
- 函数(方法)的形参和返回值的类型注解
注意事项
- 类型注解只是提示性的,并非决定性的。数据类型和注解类型无法对应也不会导致错误
变量的类型注解
变量的类型注解语法
- 语法1:变量: 类型
- 语法2:在注释中,# type: 类型
my_tuple:tuple[int,str,bool] = (1, "nihao", True)my_tuple= (1, "nihao", True)# type:tupe[int,str,bool]class student: passstu:student=student()class student: passstu=student()# type:student类型注解小技巧:在()中CTRL+P
import小技巧:ALT+ENTER
函数和方法的类型注解
函数和方法哪些可以添加注解:
- 形参的类型注解
- 返回值的类型注解
函数(方法)类型注解的语法:
def 函数名(形参:类型,形参2:类型.....)->返回值类型: passdef add(a:int,b:int)->int: return bUnion联合类型的类型注解
什么是Union类型: 使用Union类型可以定义联合类型注解
Union的使用方法:
- 导包:from typing import Union
- 使用:Union[类型,类型2,…]
from typing import Unionmy_list:list[Union[int,str,float]] = [1, "nihao", 3.14]my_dict:dict[int,Union[int,str]]={1:2,2:"nima"}多态
抽象类: 包括-抽象方法的类叫做抽象类,抽象方法是指:没有具体实现方法(pass)称之为抽象方法
抽象方法的作用: 多用于做顶层设计(设计标准)以便子类做具体实现 也是对子类的一种软性约束,要求子类必须复写(实现)父类的一些方法并配合多态使用,获得不同的工作状态
多态: 多态是指不同类的对象可以以统一的方式调用同名方法。通过多态,Python能够将“相同方法名,针对不同对象”的操作统一起来,减少对类型的显式判断,从而提高代码的灵活性和可扩展性。
简单的说:多态是指,同一个行为使用不同的对象获得不同的状态
如,定义函数(方法),通过类型注解声明需要父类对象,实际传入子类对象进行工作,从而获得不同的工作状态。
class air: def say(self): pass def cold(self): pass def warm(self): passclass Meida(air): def warm(self): return "warm" def cold(self): return "cold" def say(self): return "嗡嗡"class Glee(air): def warm(self): return "warmG" def cold(self): return "coldG" def say(self): return "滴滴"def test(kongtiao:air): print(kongtiao.say())k1=Meida()k2=Glee()test(k1)test(k2)抽象类:
class air: def say(self): pass def cold(self): pass def warm(self): pass多态:
def test(kongtiao:air): print(kongtiao.say())