day14
笔记来源于:黑马程序员python教程,8天python从入门到精通,学python看这套就够了
目录
- day14
- 102、封装
- 三大特性
- 对用户隐藏的属性和行为
- 私有成员
- 使用私有成员
- 103、封装的课后习题
- 104、继承
- 单继承
- 多继承
- 105、复写父类成员和调用父类成员
- 复写
- 调用父类同名成员
- 106、变量的类型注解
- 类型注释的目的
- 类型注解
- 类型注解的语法
- 变量设置类型注解
- 注释中进行类型注解
- 107、函数和方法类型注释
- 函数(方法)的类型注解——形参注解
- 函数(方法)的类型注解——返回值注解
- 108、Union联合类型注释
- Union类型
- 109、多态
- 抽象类(接口)
102、封装
三大特性
面向对象包含3大主要特性:
- 封装
- 继承
- 多态
封装表示的是,将现实世界事物的:
- 属性
- 行为
封装到类中,描述为:
- 成员变量
- 成员方法
从而完成程序对现实世界事物的描述
对用户隐藏的属性和行为
现实世界中的事物,有属性和行为。
但是不代表这些属性和行为都是开放给用户使用的。
私有成员
既然现实事物有不公开的属性和行为,那么作为现实事物在程序中映射的类,也应该支持。
类中提供了私有成员的形式来支持。
- 私有成员变量
- 私有成员方法
定义私有成员的方式非常简单,只需要:
- 私有成员变量:变量名以 __开头(2个下划线)
- 私有成员方法:方法名以 __开头(2个下划线)
即可完成私有成员的设置。
示例图如下:
使用私有成员
-
私有方法无法直接被类对象使用
-
私有变量无法赋值,也无法获取值
-
私有成员无法被类对象使用,但是可以被其它的成员使用
示例代码:
"""
演示面向对象封装思想中私有成员的使用
"""
# 定义一个类,内含私有成员变量和私有成员方法
class Phone:
# __current_voltage = None # 当前手机运行电压
# __current_voltage = 1
__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()
# error: 不能直接使用私有成员
# phone.__keep_single_core()
# print(phone.__current_voltage)
103、封装的课后习题
示例代码:
class Phone:
# __is_5g_enable = None
__is_5g_enable = True
# __is_5g_enable = False
def __check_5g(self):
if self.__is_5g_enable == True:
print("5g开启")
else:
print("5g关闭,使用4g网络")
def call_by_5g(self):
self.__check_5g()
print("正在通话中")
phone = Phone()
phone.call_by_5g()
104、继承
- 继承分为:单继承和多继承
- 使用如图语法,可以完成类的单继承。
- 继承表示:将从父类那里继承(复制)来成员变量和成员方法(不含私有)
单继承
继承前:
继承后:
示例代码:
# 演示单继承
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()
# 结果
ITCAST
4g通话
2022年新功能:5g通话
多继承
Python 的类之间也支持多继承,即一个类,可以继承多个父类。
"""
演示面向对象:继承的基础语法
"""
# 演示多继承
class Phone:
IMEI = None # 序列号
producer = "ITCAST" # 厂商
def call_by_4g(self):
print("4g通话")
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 # 功能足够了,但是为了语法不出错,因此使用 pass
my_phone = MyPhone()
my_phone.call_by_4g()
my_phone.read_card()
my_phone.write_card()
my_phone.control()
print(my_phone.producer)
# 结果
4g通话
NFC读卡
NFC写卡
红外遥控开启了
ITCAST # 派生类对基类的成员变量重新赋值,会覆盖掉基类中成员变量的值
tips:pass是占位语句,用来保证函数(方法)或类定义的完整性,表示无内容,空的意思
105、复写父类成员和调用父类成员
复写
子类继承父类的成员属性和成员方法后,如果对其“不满意”,那么可以进行复写。
即:在子类中重新定义同名的属性或方法即可。
"""
演示面向对象:继承的基础语法
"""
# 演示单继承
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单核模式,确保通话的时候省电")
print("使用5g网络进行通话")
print("关闭CPU单核模式,确保性能")
phone = MyPhone()
phone.call_by_5g()
print(phone.producer)
调用父类同名成员
一旦复写父类成员,那么类对象调用成员的时候,就会调用复写后的新成员
如果需要使用被复写的父类的成员,需要特殊的调用方式:
方式1:
- 调用父类成员
使用成员变量:父类名.成员变量
使用成员方法:父类名.成员方法(self)
方式2:
- 使用super()调用父类成员
使用成员变量:super().成员变量
使用成员方法:super().成员方法()
示例代码:
"""
演示面向对象:继承的基础语法
"""
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)
tips:
- 只能在子类内调用父类的同名成员。
- 子类的类对象直接调用会调用子类复写的成员
106、变量的类型注解
类型注释的目的
提示变量类型;
提示调用方法需传入的参数类型。
类型注解
Python在3.5版本的时候引入了类型注解,以方便静态类型检查工具,IDE等第三方工具。
类型注解:在代码中涉及数据交互的地方,提供数据类型的注解(显式的说明)。
主要功能:
- 帮助第三方IDE工具(如PyCharm)对代码进行类型推断,协助做代码提示
- 帮助开发者自身对变量进行类型注释
支持:
- 变量的类型注解
- 函数(方法)形参列表和返回值的类型注解
类型注解的语法
变量设置类型注解
基础语法: 变量: 类型
-
基础数据类型注解
# 基础数据类型注释 var1: int = 10 var2: str = "itheima" var3: 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}
-
容器类型详细注释
# 容器类型详细注释 my_list : list[int] = [1, 2, 3] my_tuple : tuple[int, str, bool] = (1, "itheima", True) my_dict : dict[str, int] = {"itheima" : 666}
tips:
- 元组类型设置类型详细注解,需要将每一个元素都标记出来
- 字典类型设置类型详细注解,需要 2 个类型,第一个是 key 第二个是value
注释中进行类型注解
除了使用 变量: 类型, 这种语法做注解外,也可以在注释中进行类型注解。
语法:
# 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
tips:PyCharm 中输入 random 后使用快捷键 alt+Enter
,可以快速导入random模块
107、函数和方法类型注释
函数(方法)的类型注解——形参注解
如图所示:
- 在编写函数(方法),使用形参data的时候,工具没有任何提示
- 在调用函数(方法),传入参数的时候,工具无法提示参数类型
这些都是因为,我们在定义函数(方法)的时候,没有给形参进行注解。
函数和方法的形参类型注解语法:
示例:
函数(方法)的类型注解——返回值注解
函数(方法)的返回值也是可以添加类型注解的。
语法如下:
示例:
"""
演示函数和方法的类型注释
"""
# 对参数进行类型注释
def add(x: int, y : int):
return x + y
# 对返回值进行类型注释
def func(data: list) -> list:
return data
print(func(1))
108、Union联合类型注释
在遇到如下字典类型时,无法用单一类型进行注释:
因此需要引入 Union[类型, ......, 类型]
进行联合类型注释。
Union类型
Union联合类型注解,在变量注解、函数(方法)形参和返回值注解中,均可使用。
tips:导包: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
func()
109、多态
多态,指的是:多种状态,即完成某个行为时,使用不同的对象会得到不同的状态。
同样的行为(函数),传入不同的对象,得到不同的状态
多态常作用在继承关系上
比如
- 函数(方法)形参声明接收父类对象
- 实际传入父类的子类对象进行工作
即:
- 以父类做定义声明
- 以子类做实际工作
- 用以获得同一行为, 不同状态
示例代码:
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)
# 结果
汪汪汪
喵喵喵
抽象类(接口)
父类Animal的speak方法,是空实现。
这种设计的含义是:
- 父类用来确定有哪些方法
- 具体的方法实现,由子类自行决定
这种写法,就叫做抽象类(也可以称之为接口)
抽象类:含有抽象方法的类称之为抽象类
抽象方法:方法体是空实现的(pass)称之为抽象方法
示例代码:
# 演示多态,使用 2 个子类来调用函数
dog = Dog()
cat = Cat()
make_noise(dog)
make_noise(cat)
# 演示抽象类
class AC:
def cool_wind(self):
"""制冷"""
pass
def hot_wind(self):
"""制热"""
pass
def swing_l_r(self):
"""左右摆风"""
pass
class Midea_AC(AC):
def cool_wind(self):
print("美的空调制冷")
def hot_wind(self):
print("美的空调制热")
def swing_l_r(self):
print("美的空调左右摆风")
class GREEN_AC(AC):
def cool_wind(self):
print("格力空调制冷")
def hot_wind(self):
print("格力空调制热")
def swing_l_r(self):
print("格力空调左右摆风")
def make_cool(ac:AC):
ac.cool_wind()
midea_ac = Midea_AC()
green_ac = GREEN_AC
make_cool(midea_ac)
make_cool(green_ac)
# 结果
美的空调制冷
格力空调制冷