一、初识对象
1. 生活中或是程序中,我们都可以使用设计表格、生产表格、填写表格的形式组织数据
2. 进行对比,在程序中:
- 设计表格,称之为:设计类(class)
- 打印表格,称之为:创建对象
- 填写表格,称之为:对象属性赋值
3.示例代码:
# 1.设计一个类(就像是平时生活中我们填的登记表)
class Student:
name = None # 记录姓名
gender = None # 记录性别
nationality = None # 记录国籍
native_place = None # 记录籍贯
age = None # 记录年龄
# 2.创建一个对象(类似于打印登记表)
stu_1 = Student()
# 3.对象属性进行赋值3(类似于我们填写登记表)
stu_1.name = "小王"
stu_1.gender = "男"
stu_1.nationality = "中国"
stu_1.native_place = "浙江省"
stu_1.age = 18
# 4.打印出来看下
print(stu_1.name)
print(stu_1.gender)
print(stu_1.nationality)
print(stu_1.native_place)
print(stu_1.age)
二、成员方法
1. 类是由哪两部分组成呢?
- 类的属性,称之为:成员变量
- 类的行为,称之为:成员方法
注意:函数是写在类外的,定义在类内部,我们都称之为方法哦
2. 类和成员方法的定义语法
3. self的作用
- 表示类对象本身的意思
- 只有通过self,成员方法才能访问类的成员变量
- self出现在形参列表中,但是不占用参数位置,无需理会
4.示例代码:
# 1.设计一个类
class Student:
name = None # 记录姓名
def say_hi(self): # 定义成员方法1
print(f"大家好呀,我是{self.name},欢迎大家多多关照")
def say_hi2(self, msg): # 定义成员方法2
print(f"大家好,我是{self.name}:{msg}")
stu = Student() # 创建一个对象
stu.name = "只因" # 对象属性赋值
stu.say_hi() # 调用方法
stu.say_hi2("你干嘛哈哈,哎呦") # 调用方法
三、类和对象
1. 现实世界的事物由什么组成?
- 属性
- 行为
类也可以包含属性和行为,所以使用类描述现实世界事物是非常合适的
2. 类和对象的关系是什么?
- 类是程序中的“设计图纸”
- 对象是基于图纸生产的具体实体
3. 什么是面向对象编程?
面向对象编程就是,使用对象进行编程。
即,设计类,基于类创建对象,并使用对象来完成具体的工作。
四、构造方法
1.构造方法的名称是:
__init__,注意init前后的2个下划线符号
2. 构造方法的作用:
- 构建类对象的时候会自动运行
- 构建类对象的传参会传递给构造方法,借此特性可以给成员变量赋值
3. 注意事项:
- 构造方法不要忘记self关键字
- 在方法内使用成员变量需要使用self
4.示例代码:
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("小王", 13, 13588855885)
print(stu.name)
print(stu.age)
print(stu.tel)
五、其他内置方法
1.常见的内置方法
我们通常把内置方法称之为魔术方法,下面是几种常见的魔术方法。
2.示例代码:
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}"
def __lt__(self, other):
return self.age < other.age
def __le__(self, other):
return self.age <= other.age
def __eq__(self, other):
return self.age == other.age
stu1 = Student("小王", 31)
stu2 = Student("小陈", 36)
print(stu1)
print(stu1 < stu2)
print(stu1 <= stu2)
print(stu1 == stu2)
六、封装
1. 封装的概念是指?
将现实世界事物在类中描述为属性和方法,即为封装。
2. 什么是私有成员?为什么需要私有成员
? 现实事物有部分属性和行为是不公开对使用者开放的。同样在类中描述属性和方法的时候也需要达到这个要求,就需要定义私有成员了
3. 如何定义私有成员?
成员变量和成员方法的命名均以__作为开头即可
4. 私有成员的访问限制?
- 类对象无法访问私有成员
- 类中的其它成员可以访问私有成员
5.示例代码
# 定义一个类,内含私有成员变量和私有成员方法
class Phone:
__current_voltage = 0.5 # 私有成员变量
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("电量不足,无法使用5g通话,并已设置为单核运行进行省电。")
phone = Phone()
phone.call_by_5g()
七、继承
(1)继承的基础语法
1. 什么是继承?
继承就是一个类,继承另外一个类的成员变量和成员方法
语法:
子类构建的类对象,可以
- 有自己的成员变量和成员方法
- 使用父类的成员变量和成员方法
# 定义父类
class Phone:
IMEI = None # 序列号
producer = "ITCAST" # 厂商
def call_by_4g(self):
print("4g通话")
# 定义子类,继承父类
class Phone2022(Phone):
face_id = "10001" # 面部识别ID
def call_by_5g(self):
print("2022年新功能:5g通话")
phone = Phone2022() # 创建对象
print(phone.producer)
phone.call_by_4g() # 调用父类方法
phone.call_by_5g() # 调用子类方法
2. 单继承和多继承
- 单继承:一个类继承另一个类
- 多继承:一个类继承多个类,按照顺序从左向右依次继承
多继承中,如果父类有同名方法或属性,先继承的优先级高于后继承
# 演示多继承
class NFCReader:
nfc_type = "第五代"
producer = "HM"
def read_card(self):
print("NFC读卡")
def write_card(self):
print("NFC写卡")
class RemoteControl:
rc_type = "红外遥控"
def control(self):
print("红外遥控开启了")
class MyPhone(Phone, NFCReader, RemoteControl):
pass
3. pass关键字的作用是什么
pass是占位语句,用来保证函数(方法)或类定义的完整性,表示无内容,空的意思
(2)复写和使用父类成员
1. 复写表示:
对父类的成员属性或成员方法进行重新定义
2. 复写的语法:
在子类中重新实现同名成员方法或成员属性即可
3. 在子类中,如何调用父类成员
注意:只可以在子类内部调用父类的同名成员,子类的实体类对象调用默认是调用子类复写的
4.示例代码
class Phone:
IMEI = None # 序列号
producer = "ITCAST" # 厂商
def call_by_5g(self):
print("使用5g网络进行通话")
# 定义子类,复写父类成员
class MyPhone(Phone):
producer = "ITHEIMA" # 复写父类的成员属性
def call_by_5g(self):
print("开启CPU单核模式,确保通话的时候省电")
# 方式1
# print(f"父类的厂商是:{Phone.producer}")
# Phone.call_by_5g(self)
# 方式2
print(f"父类的厂商是:{super().producer}")
super().call_by_5g()
print("关闭CPU单核模式,确保性能")
phone = MyPhone()
phone.call_by_5g()
print(phone.producer)
# 在子类中,调用父类成员
八、类型注解
(1)变量的类型注解
1. 什么是类型注解,有什么作用?
在代码中涉及数据交互之时,对数据类型进行显式的说明,可以帮助:
- PyCharm等开发工具对代码做类型推断协助做代码提示
- 开发者自身做类型的备注
2. 类型注解支持:
- 变量的类型注解
- 函数(方法)的形参和返回值的类型注解
3. 变量的类型注解语法
- 语法1: 变量: 类型
# 基础数据类型注解
var_1: int = 10
var_2: str = "itheima"
var_3: bool = True
# 类对象类型注解
class Student:
pass
stu: Student = Student()
# 基础容器类型注解
my_list: list = [1, 2, 3]
my_tuple: tuple = (1, 2, 3)
my_dict: dict = {"itheima": 666}
# 容器类型详细注解
# 注意:
1.元组类型设置类型详细注解,需要将每一个元素都标记出来
2.字典类型设置类型详细注解,需要2个类型,第一个是key第二个是value
my_list: list[int] = [1, 2, 3]
my_tuple: tuple[int, str, bool] = (1, "itheima", True)
my_dict: dict[str, int] = {"itheima": 666}
- 语法2: 在注释中,# type: 类型
# 在注释中进行类型注解
var_1 = random.randint(1, 10) # type: int
var_2 = json.loads('{"name": "zhangsan"}') # type: dict[str, str]
def func():
return 10
var_3 = func() # type: int
4. 注意事项
类型注解只是提示性的,并非决定性的。数据类型和注解类型无法对应也不会导致错误
(2)函数(方法)的类型注解
1. 函数(方法)可以为哪里添加注解?
- 形参的类型注解
# 对形参进行类型注解
def add(x: int, y: int):
return x + y
- 返回值的类型注解
# 使用Union类型,必须先导包
from typing import Union
my_list: list[Union[int, str]] = [1, 2, "itheima", "itcast"]
def func(data: Union[int, str]) -> Union[int, str]:
pass
2. 函数(方法)的类型注解语法?
注意,返回值类型注解的符号使用: ->
(3)Union类型
1. 什么是Union类型?
使用Union可以定义联合类型注解
2. Union的使用方式
- 导包:from typing import Union
- 使用:Union[类型, ......, 类型]
# 使用Union类型,必须先导包
from typing import Union
my_list: list[Union[int, str]] = [1, 2, "itheima", "itcast"]
def func(data: Union[int, str]) -> Union[int, str]:
pass
九、多态
1. 什么是多态?
多态指的是,同一个行为,使用不同的对象获得不同的状态。
如,定义函数(方法),通过类型注解声明需要父类对象,实际传入子类对象进行工作,从而获得不同的工作状态
2. 什么是抽象类(接口)
包含抽象方法的类,称之为抽象类。抽象方法是指:没有具体实现的方法(pass)称之为抽象方法
3. 抽象类的作用
多用于做顶层设计(设计标准),以便子类做具体实现。
也是对子类的一种软性约束,要求子类必须复写(实现)父类的一些方法 并配合多态使用,获得不同的工作状态。
4.示例代码
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对象"""
animal.speak()
# 演示多态,使用2个子类对象来调用函数
dog = Dog()
cat = Cat()
make_noise(dog)
make_noise(cat)