面向对象
面向对象编程,是许多编程语言都支持的一种编程思想。
基于模板(类)去创建实体(对象),使用对象去完成功能开发
面向对象的三大特性
- 封装
- 继承
- 多态
封装
封装表示:将现实世界事物的属性和行为,封装到类中,描述成为成员变量和成员方法
私有成员
既然现实事物有不公开的属性和方法,那么作为现实事物在程序中映射的类,也应该支持
类中提供了私有成员的形式来支持
- 私有成员变量
- 私有成员方法
定义私有成员的方式
- 私有成员变量:变量名以__开头(两个下划线)
- 私有成员方法:方法名以__开头(两个下划线)
使用私有成员
class Phone:
IMEI = None # 序列号
producer = None # 厂商
__current_voltage = None # 当前电压
def call_by_5g(self):
print("5G通话已经开通")
def __keep_single_core(self):
print("让cpu以单核模式运行")
phone = Phone() # 创建对象
phone.__keep_single_core() # 使用私有方法
私有方法无法被对象直接使用
使用私有变量
class Phone:
IMEI = None # 序列号
producer = None # 厂商
__current_voltage = 30 # 当前电压
def call_by_5g(self):
print("5G通话已经开通")
def __keep_single_core(self):
print("让cpu以单核模式运行")
phone = Phone() # 创建对象
print(phone.__current_voltage)
私有变量无法直接使用
私有成员的意义
在类中提供仅供内部使用的属性和方法,而且不对外开放(类对象无法使用)
继承
继承分为:单继承和多继承
继承表示:将从父类那里继承(复制)来成员变量和成员方法(不含私有成员)
单继承
class Phone:
IMEI = None # 序列号
producer = "HW" # 厂商
def call_by_4g(self):
print("4g通话")
class Phone2024(Phone):
face_id = "10001" # 面部识别id
def call_by_5g(self):
print("2024新功能:5g通话")
phone = Phone2024()
print(phone.producer) # 子类调用父类的属性
phone.call_by_5g()
多继承
python支持多继承,一个类可以继承多个父类
class 类名(父类1,父类2,父类3...):
内容体
class Phone:
IMEI = None # 序列号
producer = "HW" # 厂商
def call_by_5g(self):
print("5g通话")
class NFCReader:
nfc_type = "第六代"
producer = "XM"
def read_card(self):
print("读取NFC卡")
def write_card(self):
print("写入nfc卡")
class RemoteController:
rc_type = "红外遥控"
def controller(self):
print("红外遥控开启")
class MyPhone(Phone, NFCReader, RemoteController):
pass
phone = MyPhone()
phone.call_by_5g()
phone.read_card()
phone.write_card()
phone.controller()
print(phone.producer)
多继承的注意事项
多个父类,如有同名的成员,那么默认以继承顺序(从左到右)为优先级
即:先继承的保留,后继承的被覆盖
比如上面的案例中的Phone和NFCReader类中都有producer成员属性
然后继承的时候先继承Phone,所以print(phone.producer)打印的时候打印出的是Phone中的producer的值
pass关键字
pass是占位语句,保证函数、方法、类的完整性,表示无内容,空的意思
重写和使用父类成员
重写
子类继承父类成员属性和方法后,如果对其不满意。那么可以进行重写
即:在子类中重新定义同名的属性和方法即可
class Animal:
name = "动物"
def call(self):
print("动物会叫")
class Cat(Animal):
name = "小花猫"
def call(self):
print("小花猫喵喵叫")
cat = Cat()
print(cat.name)
cat.call()
Cat类重写的了父类Animal中的属性和方法
使用父类成员
第一种方式:
调用父类成员
使用成员变量:父类名.成员变量
使用成员方法:父类名.成员方法(self)
class Animal:
name = "动物"
def call(self):
print("动物会叫")
class Cat(Animal):
name = "小花猫"
def call(self):
print(Animal.name)
Animal.call(self)
print("小花猫喵喵叫")
cat = Cat()
cat.call()
第二种方式:
使用super()调用父类成员
使用成员变量:super().成员变量
使用成员方法:super().成员方法()
class Animal:
name = "动物"
def call(self):
print("动物会叫")
class Cat(Animal):
name = "小花猫"
def call(self):
print(super().name)
super().call()
print("小花猫喵喵叫")
cat = Cat()
cat.call()
注意:只可以在子类内部调用父类的同名成员,子类的实体类对象调用默认是调用子类重写
多态
多态指的是多种状态,即完成某个行为,使用不同的对象会得到不同的状态
class Animal:
def spake(self):
pass
class Dog(Animal):
def spake(self):
print("汪汪汪")
class Cat(Animal):
def spake(self):
print("喵喵喵")
def make_noise(animal: Animal):
animal.spake()
dog = Dog()
cat = Cat()
make_noise(dog)
make_noise(cat)
多态经常作用在继承关系上
比如:
- 函数(方法)形参声明接收父类对象
- 实际传入父类的子类对象进行工作
即:
- 以父类做定义声明
- 以子类做实际工作
- 用以获得同一行为,不同状态
抽象类(接口)
父类的Animal的spake方法,是空实现
这种设计的含义是:
- 父类用来确定有哪些方法
- 具体的方法实现,由子类决定
这种写法就叫做抽象类(也可以称之为接口)
抽象类:含有抽象方法的类
抽象方法:方法体是空实现的(pass)称之为抽象方法
为什么要使用抽象类
提出标准后
不同的厂家各自实现标准的要求
抽象类就好比定义一个标准
包含了一些抽象的方法,要求子类必须实现
配合多态,完成:
- 抽象的父类设计(设计标准)
- 具体的子类实现(实现标准)
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 GREE_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()
def make_hot(ac: AC):
ac.hot_wind()
def make_swing(ac: AC):
ac.swing_l_r()
midea_ac = Midea_AC()
gree_ac = GREE_AC()
make_cool(midea_ac)
make_cool(gree_ac)
抽象类的作用:多用于顶层设计(设计标准),以便子类做具体实现
也是对子类的一种软性约束,要求子类必须重写(实现)父类的一些方法