目录
一、初识对象
使用对象组织数据
在程序中是可以做到和生活中那样,设计表格、生产表格、填写表格的组织形式的。
1. 在程序中设计表格,我们称之为:设计类(class)
class student:
name=None
2. 在程序中打印生产表格,我们称之为:创建对象
#基于类创建对象
stu_1=student()
stu_1=student()
3. 在程序中填写表格,我们称之为:对象属性赋值
#基于类创建对象
stu_1.name='盐汽水'
stu_2.name='小海螺'
二、成员方法
1、类的定义和使用
class是关键字,表示要定义类了
类的属性,即定义在类中的变量(成员变量)
类的行为,即定义在类中的函数(成员方法)
创建类对象:
2、成员变量和成员方法
类中定义的属性(变量),我们称之为:成员变量
class student:
name=None
age=None
类中定义的行为(函数),我们称之为:成员方法
def say_hi(self,msg):
print(f'hello,{msg}')
stu=student()
stu.name='盐汽水'
stu.say_hi()
3、成员方法的定义语法
self关键字是成员方法定义的时候,必须填写的。self出现在形参列表中,但是不占用参数位置,无需理会。
它用来表示类对象自身的意思 当我们使用类对象调用方法的是,self会自动被python传入(传参的时候不用管)
在方法内部,成员方法想要访问类的成员变量,必须使用self
class student:
name=None
def say_hi(self):
print('hello')
def say_hi(self,msg):
print(f'hello,{msg}')
stu=student()
print(stu.say_hi())#调用时无需传参
print(stu.say_hi2("i'm fine"))#传不是self的参即可
可以看到,在传入参数的时候,self是透明的,可以不用理会它。
三、类和对象
类只是一种程序内的“设计图纸”,需要基于图纸生产实体(对象),才能正常工作 这种套路,称之为:面向对象编程
即设计类,基于类创建对象,由对象做具体的工作
1. 类和对象的关系是什么?
类是程序中的“设计图纸”
对象是基于图纸生产的具体实体
2. 什么是面向对象编程?
面向对象编程就是,使用对象进行编程。
即,设计类,基于类创建对象,并使用对象来完成具体的工作
四、构造方法
Python类可以使用:__init__()方法,称之为构造方法。
前后都有2个下划线
在创建类对象(构造类)的时候,会自动执行。
在创建类对象(构造类)的时候,将传入参数自动传递给__init__方法使用。
构造方法也是成员方法,不要忘记在参数列表中提供:self
class student:
name=None
age=None
tel=None
#上边三条可以省略,省略了下边就是对成员变量声明
def __init__(self,name,age,tel):
self.name=name
self.age=age
self.tel=tel
print('student类创建了一个对象')
stu=student('盐汽水',18,'6156214')
print(stu.name)
print(stu.age)
print(stu.tel)
在构造方法内定义成员变量,需要使用self关键字,变量是定义在构造方法内部,如果要成为成员变量,需要用self来表示。
五、其他内置方法
魔术方法
1、__str__
class Student:
def __init__(self,name,age):
self.name=name
self.age=age
student=Student('盐汽水',18)
print(student)#==><__main__.Student object at 0x00000202A1601E80>
print(str(student))#==><__main__.Student object at 0x00000202A1601E80>
当类对象需要被转换为字符串时,会输出如上结果(内存地址)
内存地址没有多大作用,我们可以通过__str__方法,控制类转换为字符串的行为。
提供__str__ 在要转换成字符串时输出是自己定制的字符串
class Student:
def __init__(self,name,age):
self.name=name
self.age=age
def __str__(self):
return f'Student类对象,name={self.name},age={self.age}'
student=Student('盐汽水',18)
print(student)#==>Student类对象,name=盐汽水,age=18
print(str(student))#==>Student类对象,name=盐汽水,age=18
2、__lt__ --> <
传入参数:other,另一个类对象
返回值:True 或 False
内容:自行定义
比较大于符号的魔术方法是:__gt__
不过,实现了__lt__,__gt__就没必要实现了
class Student:
def __init__(self,name,age):
self.name=name
self.age=age
student1=Student('盐汽水',18)
student2=Student('小海螺',19)
print(student1<student2)
#错误!不支持这两者比较
直接对2个对象进行比较是不可以的,但是在类中实现__lt__方法,即可同时完成:小于符号 和 大于符号 2种比较
class Student:
def __init__(self,name,age):
self.name=name
self.age=age
def __lt__(self,other):
return self.age<other.age
student1=Student('盐汽水',18)
student2=Student('小海螺',19)
print(student1<student2)#==>True
print(student1>student2)#==>False
3、__le__ --> <=
传入参数:other,另一个类对象
返回值:True 或 False
内容:自行定义
>=符号实现的魔术方法是:__ge__
不过,实现了__le__,__ge__就没必要实现了
class Student:
def __init__(self,name,age):
self.name=name
self.age=age
def __le__(self,other):
return self.age<=other.age
student1=Student('盐汽水',18)
student2=Student('小海螺',19)
print(student1<=student2)#==>True
print(student1>=student2)#==>False
4、__eq__ -->==
传入参数:other,另一个类对象
返回值:True 或 False
内容:自行定义
class Student:
def __init__(self,name,age):
self.name=name
self.age=age
def __eq__(self,other):
return self.age==other.age
student1=Student('盐汽水',18)
student2=Student('小海螺',19)
print(student1==student2)#==>False
不实现__eq__方法,对象之间可以比较,但是是比较内存地址,也即是:不同对象==比较一定是False结果。
实现了__eq__方法,就可以按照自己的想法来决定2个对象是否相等了。
总结
方法 | 功能 |
__init__ | 构造方法,可用于创建类对象的时候设置初始化行为 |
__str__ | 用于实现类对象转字符串的行为 |
__lt__ | 用于2个类对象进行小于或大于比较 |
__le__ | 用于2个类对象进行小于等于或大于等于比较 |
__eq__ | 用于2个类对象进行相等比较 |
六、面向对象的三大特性:
面向对象编程,是许多编程语言都支持的一种编程思想。 简单理解是:基于模板(类)去创建实体(对象),使用对象完成功能开发。
面向对象包含3大主要特性:
封装 继承 多态
1、封装
封装表示的是,将现实世界事物的:属性 行为
封装到类中,描述为: 成员变量 成员方法
私有成员-->只能内部自己使用,对象不能用
现实事物有部分属性和行为是不公开对使用者开放的。同样在类中描述属性和方法的时候也需要达到这个要求
类中提供了私有成员的形式来支持 私有成员变量 私有成员方法
定义私有成员的方式非常简单,只需要:
私有成员变量:变量名以__开头(2个下划线)
私有成员方法:方法名以__开头(2个下划线) 即可完成私有成员的设置
class Phone:
__current_voltage=None
def __keep_single_core(self):
print('让CPU以单核运行')
phone=Phone()
print(phone.__current_voltage)#==>报错
phone.__keep_single_core#==>报错
私有方法无法直接被类对象使用
私有成员无法被类对象使用,但是可以被其它的成员使用
class Phone:
__current_voltage=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('电量不足')
phone=Phone()
phone.call_by_5g()#-->5g通话已开启
类对象无法访问私有成员
类中的其它成员可以访问私有成员
私有成员意义:在类中提供仅供内部使用的属性和方法,而不对外开放(类对象无法使用)
2、继承
继承就是一个类,继承另外一个类的成员变量和成员方法
继承分为:单继承和多继承 使用如图语法,可以完成类的单继承。
继承表示:将从父类那里继承(复制)来成员变量和成员方法(不含私有)
1)单继承
一个类继承另一个类
class Phone:
IMEI=None
producer=None
def call_by_4g(self):
print("4g通话")
class Phone2022(Phone):#继承->Phone 里的都能用
face_id=True #新功能
def call_by_5g(self):
print("5g通话")
phone=Phone2022()
phone.call_by_4g()#-->4g通话
2)多继承
一个类继承多个类,按照顺序从左向右依次继承
Python的类之间也支持多继承,即一个类,可以继承多个父类
class Phone:
IMEI=None
producer=None
def call_by_5g(self):
print("5g通话")
class NFCReader:
nfc_type='第五代'
producer='HM'
def read_carf(self):
print("读取NFC卡")
def write_card(self):
print("写入NFC")
class RemoteCoontrol:
rc_type="红外遥控"
def control(self):
print("红外遥控开启")
class MyPhone(Phone,NFCReader,RemoteCoontrol):
pass
phone=MyPhone()
phone.call_by_5g()
phone.read_carf()
phone.write_card()
phone.control()
多个父类中,如果有同名的成员,那么默认以继承顺序(从左到右)为优先级。 即:先继承的保留,后继承的被覆盖
子类构建的类对象,可以 :
1)有自己的成员变量和成员方法 2)使用父类的成员变量和成员方法
pass关键字的作用: pass是占位语句,用来保证函数(方法)或类定义的完整性,表示无内容,空的意思
3)复写
对父类的成员属性或成员方法进行重新定义
子类继承父类的成员属性和成员方法后,如果对其“不满意”,那么可以进行复写。 即:在子类中重新定义同名的属性或方法即可。
class Phone:
IMEI=None
producer="盐汽水"
def call_by_5g(self):
print("父类的5g通话")
class MyPhone(Phone):
producer="小海螺"
def call_by_5g(self):
print("子类的5g通话")
phone=MyPhone()
phone.call_by_5g()#-->子类的5g通话
调用父类同名成员
一旦复写父类成员,那么类对象调用成员的时候,就会调用复写后的新成员 如果需要使用被复写的父类的成员,需要特殊的调用方式:
方式1:
调用父类成员
使用成员变量:父类名.成员变量
使用成员方法:父类名.成员方法(self)
方式2: 使用super()调用父类成员
使用成员变量:super().成员变量
使用成员方法:super().成员方法()
注意:只可以在子类内部调用父类的同名成员,子类的实体类对象调用默认是调用子类复写的
法一:
class Phone:
IMEI=None
producer="盐汽水"
def call_by_5g(self):
print("父类的idol头衔")
class MyPhone(Phone):
producer="小海螺"
def call_by_5g(self):
print(f'父类的idol头衔是{Phone.producer}')#->父类的idol头衔是盐汽水
Phone.call_by_5g(self)#->父类的idol头衔
print("子类的idol头衔")
phone=MyPhone()
phone.call_by_5g()
法二:
class Phone:
IMEI=None
producer="盐汽水"
def call_by_5g(self):
print("父类的idol头衔")
class MyPhone(Phone):
producer="小海螺"
def call_by_5g(self):
print(f'父类的idol头衔是{super().producer}')#->父类的idol头衔是盐汽水
super().call_by_5g()#->父类的idol头衔
print("子类的idol头衔")
phone=MyPhone()
phone.call_by_5g()
3、类型注解
一、PyCharm确定这个对象,是list类型,就可以提示
二、当我们调用方法,进行传参的时候(快捷键ctrl + p弹出提示):
提示传入2个参数 类型是int
类型注解:在代码中涉及数据交互的地方,提供数据类型的注解(显式的说明)。 主要功能:
主要功能:
帮助第三方IDE工具(如PyCharm)对代码进行类型推断,协助做代码提示
帮助开发者自身对变量进行类型注释
支持:
变量的类型注解
函数(方法)形参列表和返回值的类型注解
类型注解的语法
1、为变量设置类型注解 基础语法: 变量: 类型
元组类型设置类型详细注解,需要将每一个元素都标记出来
字典类型设置类型详细注解,需要2个类型,第一个是key第二个是value
2、 也可以在注释中进行类型注解
语法: # type: 类型
class Student:
pass
var_1=random.randint(1,10) #type:int
var_2=json.loads('{"name":"zhangsna"}') #type:dict[str,str]
var_3=Student() #type:Student
一般,无法直接看出变量类型之时 会添加变量的类型注解
并不会真正的对类型做验证和判断。 也就是,类型注解仅仅是提示性的,不是决定性的
如图代码,是不会报错的
函数(方法)的类型注解 - 形参注解
函数和方法的形参类型注解语法:
函数(方法)的类型注解 - 返回值注解
注意,返回值类型注解的符号使用: ->
Union类型
使用Union[类型, ......, 类型] 可以定义联合类型注解
Union的使用方式 导包:from typing import
Union 使用:Union[类型, ......, 类型]
Union联合类型注解,在变量注解、函数(方法)形参和返回值注解中,均可使用。
3、多态
同样的行为(函数),传入不同的对象,得到不同的状态
多态常作用在继承关系上.
比如 函数(方法)形参声明接收父类对象 实际传入父类的子类对象进行工作
即: 以父类做定义声明 以子类做实际工作 用以获得同一行为, 不同状态
class Animal:
def speak(self):
pass
class Dog(Animal):
def speak(self):
print("汪汪汪")
class Cat(Animal):
def speak(self):
print("喵喵喵")
def make_noise(animal:Animal):
animal.speak()
dog=Dog()
cat=Cat()
make_noise(dog)#汪汪汪
make_noise(cat)#喵喵喵
父类Animal的speak方法,是空实现,这种设计的含义是:
父类用来确定有哪些方法 具体的方法实现,由子类自行决定
这种写法,就叫做抽象类(也可以称之为接口)
抽象类(接口):含有抽象方法的类称之为抽象类,抽象类就好比定义一个标准, 包含了一些抽象的方法,要求子类必须实现。
抽象方法:方法体是空实现的(pass)称之为抽象方法
配合多态,完成:
抽象的父类设计(设计标准)
具体的子类实现(实现标准)
class AC:
def cool_wind(self):
'''制冷'''
pass
def hot_wind(self):
'''制热'''
pass
def swing(self):
'''左右摆风'''
class Midea(AC):
def cool_wind(self):
print("美的空调核心制冷")
def hot_wind(self):
print("美的空调核电热丝加热")
def swing(self):
print("美的空调左右摆风")
class GREE(AC):
def cool_wind(self):
print("格力空调核心制冷")
def hot_wind(self):
print("格力空调核电热丝加热")
def swing(self):
print("格力空调左右摆风")
def make_cool(ac:AC):
ac.cool_wind()
Midea_AC=Midea()
GREE_AC=GREE()
make_cool(Midea_AC)#美的空调核心制冷
make_cool(GREE_AC)#格力空调核心制冷