27.封装-继承-多态

面向对象有三大特性

面向对象编程,是许多编程语言都支持的一种编程思想

简单理解是:基于模板(类)去创建实体(对象),使用对象完成功能开发

面向对象包含三大主要特性:

  • 封装
  • 继承
  • 多态

封装

封装表示的是,将现实世界事物的:属性、行为 封装到类中,描述为:成员变量、成员方法 从而完成程序对现实世界事物的描述

对用户隐藏的属性和行为--私有成员

私有成员在类中提供仅供内部使用的属性和方法,而不对外开放(类对象无法使用)

类中提供了私有成员的形式来支持:

  • 私有成员变量
  • 私有成员方法

定义私有成员的方式非常简单,只需要:

  • 私有成员变量:变量名称__开头(2个下划线)
  • 私有成员方法:方法名称__开头(2个下划线)

定义的私有成员的方法与属性,私有无法直接被类对象使用,私有变量无法赋值,也无法获取值

# 定义一个类,内含私有成员变量和私有成员方法
class Phone:
    __current_voltage = "3.33"    # 当前手机运行电压

    def __keep_single_core(self):
        print("让CPU以单核模式运行")

phone = Phone()
# print(phone.__current_voltage)
# print.__keep_single_core()
使用私有成员

私有成员无法被类对象使用,但是类中其它成员可以使用私有成员

class Phone:
    __current_voltage = 0.33    # 当前手机运行电压

    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()
让CPU以单核模式运行,切换省电模式
电量不足,无法使用5G通话,并已设置省电模式
练习
class Phone:
    # 提供私有成员变量
    __is_5g_enable = False

    # 提供私有成员方法:
    def __check_5g(self):
        if self.__is_5g_enable:
            print("5g开启")
        else:
            print("5g关闭,使用4g网络")

    # 提供公开成员方法:
    def call_by_5g(self):
        self.__check_5g()
        print("正在通话中")

phone = Phone()
phone.call_by_5g()
5g关闭,使用4g网络
正在通话中

继承

继承分为:单继承和多继承

继承表示:将从父类那里继承(复制)来成员方法(不含私有成员)

单继承语法:

class 类名(父类名):

  类内容体

# 单继承
class Phone:
    IMEI = None
    producer = "HM"

    def call_by_4g(self):
        print("4g通话")

class Phone2023(Phone):
    face_id = "10001"

    def call_by_5g(self):
        print("2022年新功能:5G通话")

phone = Phone2023()
print(phone.producer)
phone.call_by_4g()
phone.call_by_5g()
HM
4g通话
2022年新功能:5G通话

多继承语法:

class 类名(父类1, 父类2, 父类3, ......, 父类N):

  类内容体

注意:多继承中,如果父类有同名方法或属性,先继承的优先级高于后继续的父类

# 多继承
class Phone:
    IMEI = None
    producer = "HM"

    def call_by_4g(self):
        print("4g通话")

class Phone2023(Phone):
    face_id = "10001"

    def call_by_5g(self):
        print("2022年新功能:5G通话")

class NFCReader():
    nfs_type = "第五代"
    producer = "ITCAST"

    def read_card(self):
        print("NFC读卡")
    def write_card(self):
        print("NFC写卡")

class RemoteControl():
    rc_type = "红外遥控"

    def control(self):
        print("红外遥控")

class MyPhone(Phone2023, NFCReader, RemoteControl):
    pass                       # 不想添加新功能新内容。使用pass占位语句表示无内容空的意思  补全语法不产生错误

phone = MyPhone()
print(phone.producer)     # 引用的父类里面有属性相同时,按照继承的顺序优先
phone.call_by_4g()
phone.call_by_5g()
phone.read_card()
phone.control()
HM
4g通话
2022年新功能:5G通话
NFC读卡
红外遥控

复写父类成员

子类继承父类的成员属性和成员方法后,如果对其“不满意”,那么可以进行复写

即:在子类中重新定义同名的属性和方法即可

class Phone:
    IMEI = "xxxzzz"
    producer = "HM"

    def call_by_5g(self):
        print("父类5g通话")

class Phone2023(Phone):
    producer = "ITCAST"

    def call_by_5g(self):
        print("子类5g通话")

phone = Phone2023()
print(phone.IMEI)
print(phone.producer)
phone.call_by_5g()
xxxzzz
ITCAST
子类5g通话

调用父类同名成员

一旦复写父类成员,那么类对象调用成员的时候,就会调用复写后的新成员

如果需要使用被复写的父类成员,需要特殊的调用方式:

  • 调用父类成员 使用成员量:父类名.成员变量 使用成员方法:父类名.成员方法()
  • 使用super()调用父类成员 使用成员变量:super().成员变量 super().成员方法()
class Phone:
    IMEI = "xxxzzz"
    producer = "HM"

    def call_by_5g(self):
        print("父类5g通话")

class Phone2023(Phone):
    producer = "ITCAST"

    def call_by_5g(self):
        # 方式1
        print(f"父类的厂商是:{Phone.producer}")
        Phone.call_by_5g(self)

        # 方式2
        print(f"父类的厂商是:{super().producer}")
        super().call_by_5g()

        print("子类5g通话")

phone = Phone2023()
print(phone.IMEI)
print(phone.producer)
print("-----------------------------")
phone.call_by_5g()
xxxzzz
ITCAST
父类的厂商是:HM
父类5g通话
父类的厂商是:HM
父类5g通话
子类5g通话

多态

多态,指的是:多种状态,即完成某个行为时,使用不同的对象会得到不同的状态

同样的行为(函数),传入不同的对象,得到不同的状态

多态常作用在继承关系上

比如

  • 函数(方法)形参声明接收父类对象
  • 实际传入父类的子类对象进行工作

即:

  • 以父类做定义声明
  • 以子类做实际工作
  • 用以获得同一行为,不同状态

如下代码所示,父类Animal的speak方法,是空实现

这种设计的含义是:

  • 父类用来确定有哪些方法
  • 具体的方法实现,由子类自行决定

这种写法,就叫做抽象类(也可以称之为接口)

抽象类: 含有抽象方法的类称之为抽象类

抽象方法:方法体是空实现的(pass)称之为抽象方法

抽象类配合多态,完成:

  • 抽象的父类设计(设计标准)
  • 具体的子类实现(实现标准)

抽象类的作用:

  • 多用于顶层设计(设计标准),以便子类做具体实现
  • 也是对子类的一种软性约束,要求子类必须复写(实现)父类的一些方法
  • 并配合多态使用,获得不同的工作状态
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(cat)
make_noise(dog)
喵喵喵
汪汪汪
# 定义一个抽象类
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()

midea_ac = Midea_AC()
gree_ac = Gree_AC()

make_cool(midea_ac)
make_cool(gree_ac)
美的制冷科技
格力制冷科技