一 初识对象
说白了就是类的实例化,类是一个抽象层的定义。
例如下面class Student就是定义的一个类,它是抽象层,然后stu_1 = Student(),我们根据类创建了一个对象,就是对类的实例化,这个实例化对象我们是可以操作的。
if __name__ == '__main__':# 1.设计一个类(类比生活中:设计一张登记表)class Student:name = None # 记录学生姓名gender = None # 记录学生性别nationality = None # 记录学生国籍native_place = None # 记录学生籍贯age = None # 记录学生年龄# 2.创建一个对象(类比生活中:打印- -张登记表)stu_1 = Student()# 3.对象属性进行赋值(类比生活中:填写表单)stu_1.name = "林军杰"stu_1.gender = "男"stu_1.nationality = "中国"stu_1.native_place = "山东省"stu_1.age = 31# 4.获取对象中记录的信息print(stu_1.name )print(stu_1.gender)print(stu_1.nationality)print(stu_1.native_place)
二 类的成员方法
现在我们来看看类的使用语法:
class 类名称:类的属性类的行为
- class是关键字, 表示要定义类了。
- 类的属性,即定义在类中的变量(成员变量)。
- 类的行为, 即定义在类中的函数(成员方法)。
- 创建类对象的语法对象=类名称()。
if __name__ == '__main__':# 1.设计一个类(类比生活中:设计一张登记表)class Student:name = None # 记录学生姓名def say_hi(self):print("he")def say_hi2(self,msg):print(f"hi,{msg}")# 调用方法s1 = Student()s1.say_hi()s1.say_hi2("wnm")
可以看到,在传入参数的时间,self是透明的,可以不用理会他。
if __name__ == '__main__':# 1.设计一个类(类比生活中:设计一张登记表)class Student:name = None # 记录学生姓名def say_hi(self):print("he",self.name)s1 = Student()s1.name = "wnm"s1.say_hi()#he wnm
三 构造方法
上面红色框是可以省略的,如果省略,在__init__函数中,那三行就相当于定义且赋值。而不省略,__init__函数就相当于仅赋值。
四 魔术方法
- __init__函数:构造函数。
- __str__函数:用于自定义打印对象。因为不定义的话,默认是打印出对象地址,而在python中地址没啥用。
- __lt__函数:用于对象之间的小于、大于比较。
- __le__函数:用于对象之间小于等于、大于等于的比较。
- __eq__函数:用于对象之间是否相等的比较。
注意,上面这些魔术方法是用于自定义类时要用的,因为你自定义类,例如你要比较这个类的两个对象的大小,你不提供比较方法,python是不知道怎么比较的。
if __name__ == '__main__':class Student:# 构造函数def __init__(self, name, age):self.name = nameself.age = age# __str__魔术方法def __str__(self):return f"Student类对象,name:{self.name}, age:{self.age}"# __lt__魔术方法.def __lt__(self, other):return self.age < other.agedef __le__(self, other):return self.age <= other.agedef __eq__(self, other):return self.age == other.agestu1 = Student("周杰轮", 3)stu2 = Student("周轮", 3)# 测试__str__魔术方法print(stu1)# 测试__lt__魔术方法print(stu1 < stu2)# 测试__le__魔术方法print(stu1 <= stu2)# 测试__eq__魔术方法print(stu1 == stu2)
五 封装
面向对象编程,是许多编程语言都支持的一种编程思想。
简单理解是:基于模板(类)去创建实体(对象) ,使用对象完成功能开发。
面向对象包含3大主要特性:
➢封装。
➢继承。
➢多态。
例如我们将成员属性和成员方法封装到类中,就是封装。继承和多态要继续看下面的内容。
私有成员的定义:
如果不在变量名或者方法名前增加2个下划线,那么就是公有的变量或者方法,对象可以直接访问公有成员,而无法访问私有成员,但私有成员可以被类内的其它成员访问。
if __name__ == '__main__':class Phone:__current_voltage = 0.5# 当前手机运行电压def __keep_single_core(self):print("让CPU以单核模式运行")# 类内的方法可以使用私有成员__current_voltagedef call_by_5g(self):if self.__current_voltage >= 1:print("5g通话已开启")else:self.__keep_single_core()print("电量不足,无法使用5g通话,并已设置为单核运行进行省电。")phone = Phone()phone.call_by_5g()# 对象可以调用公有方法print(phone.__current_voltage) # 报错,对象无法使用类私有成员phone.__current_voltage = 1 # 不报错,但相当于重新定义一个__current_voltage,与Phone内的__current_voltage不是同一个东西
六 继承的基础语法
6.1 单继承
语法:
class 类名(父类名):类内容体
例如:
继承之后,Phone2022同样可以使用Phone的成员和方法。
6.2 多继承
其中pass关键字是补全语法,表示定义一个空的。让语法补充,避免错误。当输出同名属性时,以前面为准,听父类的。
七 复写父类成员和调用父类成员
7.1 复写父类成员
什么是复写?
if __name__ == '__main__':class Phone:IMEI = None# 序列号producer = "ITCAST" # 厂商def call_by_5g(se1f):print("父类的5g通话")class MyPhone(Phone):proucer = "ITHEIMA"# 复写父类属性def call_by_5g(se1f):# 复写父类方法print("子类的5g通话")phone = MyPhone()print(phone.proucer)phone.call_by_5g()'''ITHEIMA子类的5g通话'''
7.2 调用父类成员
调用父类的同名成员。
if __name__ == '__main__':class Phone:IMEI = None # 序列号producer = "ITCAST" # 厂商def call_by_5g(se1f):print("父类的5g通话")class MyPhone(Phone):proucer = "ITHEIMA"# 复写父类属性def call_by_5g(se1f):# 调用父类方法# 方法1:print(f"父类的厂商是:{Phone.producer}")print("子类的5g通话")Phone.call_by_5g(se1f)# 方法2:print(f"父类的厂商是:{super().producer}")super().call_by_5g()phone = MyPhone()print(phone.proucer)phone.call_by_5g()
八 变量的类型注解
8.1 为何要类型注解
8.2 为变量设置类型注解
8.2 类型注解的限制
if __name__ == '__main__':# 基础数据类型注解var_1: int = 10var_2: str = "itheima"var_3: bool = True# 类对象类型注解class Student:passstu:Student = Student()# 基础容器类型注解.my_list: list = [1, 2, 3]my_tupLe: tuple = (1, 2,3)my_dict: dict = {"itheima": 666}# 在注释中进行类型注解my_list = [1, 2, 3] # type: listmy_tuple = ("itheima", 666, True) # type: tuple[str, int, bool]# 类型注解的限制var_7: str = 10 #没事 但是是给自己看的
九 函数和方法类型注解
十 Union联合类型注解
出现混合类型时,可以通过Union联合类型添加注解。
十一 多态
多态:完成某个行为时,使用不同的对象会得到不同的状态。