面向对象详解,面向对象的三大特征:封装、继承、多态-2

简介: 面向对象详解,面向对象的三大特征:封装、继承、多态

面向对象详解,面向对象的三大特征:封装、继承、多态-1

https://developer.aliyun.com/article/1538240


三、面向对象的三大特征:封装、继承、多态

1. 封装

封装(Encapsulation):将数据和操作封装在对象中,使其成为一个独立的实体,外界只能通过对象提供的接口访问和操作内部数据。

998734aa6a5066b055daf192dca59f4f_a7736dce01be4f309034568c9a5fa27c.png

对用户隐藏的属性和行为

现实世界中的事物,有属性和行为。但是不代表这些属性和行为都是开放给用户使用的。


私有成员

既然现实事物有不公开的属性和行为,那么作为现实事物在程序中映射的类,也应该支持。


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

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

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

  • 私有成员变量:变量名以__开头(2个下划线)
  • 私有成员方法:方法名以__开头(2个下划线)
class Phone:
    IMEI = None  # 序列号
    producer = None  # 厂商
    # 私有成员变量
    __current_voltage = None  # 当前电压

    def call_by_5g(self):
        print('5g通话已开启')
  
  # 私有成员方法
    def __keep_5g(self):
        print('保持5g')

私有方法无法直接被类对象使用

phone = Phone()
phone.__keep_5g()

8724d858e54a9f4c236f35aab2bfa5ba_0fe416f6651049b1be9cf7f64456be7a.png

使用私有成员

class Phone:
    # 构造方法
    def __init__(self, __is_5g_enable):
        # 设置私有变量
        self.__is_5g_enable = __is_5g_enable

    # 设置私有方法
    def __check_5g(self):
        if self.__is_5g_enable == True:  # 类内部访问私有成员要用self
            print('5G开启')
        else:
            print('5G关闭,使用4G网络')

    def call_by_5g(self):
        self.__check_5g()
        print('正在通话中...')

phone = Phone(False)
phone.call_by_5g()

2. 继承

继承(Inheritance):继承允许一个类(子类)继承另一个类(父类)的属性和方法,子类可以重用父类的代码,并且可以在不修改原有代码的情况下进行扩展和修改。

简单来说就是一个类,继承另外一个类的成员变量和成员方法


举个简单的例子:

手机的更新换代并不是完完全全重新开始,而是在原先的基础上新添一些属性和功能。

e7427b36d33ac432b7e0c392e4707993_792e2a9292d54a6892fddafcd818b918.png

类比到程序中,我们也可以在已经设计好的类上进行更新和修改,这就会用到继承。


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


单继承语法:


class 类名(父类):
  类内容体
# 单继承演示
# 定义父类
class Phone:
    IMEI = None  # 序列号
    producer = 'APPLE'  # 厂商

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

# 定义子类
class Phone2022(Phone):
    face_id = '10001'

    def call_by_5g(self):
        print('5g通话')

phone = Phone2022()
phone.call_by_4g()  # 输出:4g通话
print(phone.producer)  # 输出:APPLE
phone.call_by_5g()  # 输出:5g通话
print(phone.face_id)  # 输出:10001

通过继承可以将从父类那里继承(复制)来成员变量和成员方法(不含私有)给子类使用。


多继承语法

Python的类之间也支持多继承,即一个类,可以继承多个父类


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

举例:

d09e6f9c2ce2f2f14f5b093f22c04ae5_bf39ad311e044233b80bd44f322236b1.png


# 多继承演示
# 定义父类
class Phone:
    IMEI = None  # 序列号
    producer = 'HM'  # 厂商

    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

phone = MyPhone()
print(phone.producer)  # 输出:HM
print(phone.nfc_type)  # 输出:第五代
phone.read_card()  # 输出:读取NFC卡
phone.call_by_4g()  # 输出:4g通话
phone.control()  # 输出:红外遥控开启

多继承注意事项:多个父类中,如果有同名的成员,那么**默认以继承顺序(从左到右)**为优先级。即:先继承的保留,后继承的被覆盖。


pass语句

pass是占位语句,用来保证函数(方法)或类定义的完整性,表示无内容,空的意思。


复写

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

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


# 定义父类
class Phone:
    IMEI = None  # 序列号
    producer = 'APPLE'  # 厂商

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

# 定义子类
class MyPhone(Phone):
    producer = 'HUAWEI'  # 复写父类属性

    def call_by_4g(self):  # 复写父类方法
        print('可用5g通话')

phone = MyPhone()
print(phone.producer)  # 输出:HUAWEI
phone.call_by_4g()  # 输出:可用5g通话

调用父类同名成员

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

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


方式一:

  • 调用父类成员
    使用成员变量:父类名.成员变量
    使用成员方法:父类名.成员方法(self)

方式二:

  • 使用super()调用父类成员
    使用成员变量:super().成员变量
    使用成员方法:super().成员方法()

注意:只能在子类内调用父类的同名成员。子类的类对象直接调用会调用子类复写的成员


# 定义父类
class Phone:
    IMEI = None  # 序列号
    producer = 'APPLE'  # 厂商

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

# 定义子类
class MyPhone(Phone):
    producer = 'HUAWEI'  # 复写父类属性

    def call_by_4g(self):  # 复写父类方法
        print('可用5g通话')
        # 调用父类属性和方法
        # 方法一
        # print(f'调用父类属性[1]:{Phone.producer}')  # 调用父类属性
        # Phone.call_by_4g(self)  # 调用父类方法
        # 方法二
        print(f'调用父类属性[2]:{super().producer}')  # 调用父类属性
        super().call_by_4g()  # 调用父类方法

phone = MyPhone()
print(phone.producer)
phone.call_by_4g()

38179045adfd82948bdeff7145641383_7c0063a815e647918381f9fc10aa5497.png


3. 多态

多态(Polymorphism):多态使得对象可以根据上下文表现出不同的行为,同一个方法可以在不同对象上有不同的实现。这样可以提高代码的灵活性和可复用性。

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

如何理解?

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

多态常作用在继承关系上。

比如

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

即:

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

抽象类(接口)

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

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


举例:

8e54002ba14ec0500cfb322548b7f955_2f4dbd4d86a543779fad0d89e1d20dec.png


# 抽象类
# 定义父类
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 cool_wind(ac: AC):
    ac.cool_wind()

# 创建对象
midea = Midea_AC()
gree = GREE_AC()
cool_wind(midea)  # 输出:美的空调制冷
cool_wind(gree)  # 输出:格力空调制冷

四、类型注解

在PyCharm中编写代码,我们经常能够见到如下提示:

f43e017b86abf53ba705799f04d6fb7b_014ceab598574b8594303ebfcb02b0eb.png

为什么PyCharm工具能够做到这一点?

因为:PyCharm确定这个对象,是list类型

同样,我们换一份代码:定义一个函数func,接收一个参数data,你会发现,PyCharm不会在做出任何提示了

3b9ffc6574fe8019709cd62b8ef45367_91a69e69eabe4c9e98a1a89e9014e7d5.png

为什么PyCharm工具无法提示了?

这是因为PyCharm不确定这个对象是什么类型

PyCharm无法通过代码确定应传入什么类型,我们需要使用类型注解


1. 变量的类型注解

基础语法: 变量: 类型

为变量设置注解,显示的变量定义,一般无需注解


# 变量的类型注
var1: int = 10
var2: str = '张三'
var3: bool = True

像上面这样:就算不写注解,也明确的知晓变量的类型


2. 基础容器类型注解

# 基础容器类型注解
my_list: list = [1, 2, 3]
my_tuple: tuple = (1, 2, 3)
my_dict: dict = {"name": "张三"}

# 容器类型详细注解
my_list1: list[int] = [1, 2, 3]
my_tuple1: tuple[int, str, bool] = (1, "张三", True)
my_dict1: dict[str, str] = {"name": "张三"}

注意:

  • 元组类型设置类型详细注解,需要将每一个元素都标记出来
  • 字典类型设置类型详细注解,需要2个类型,第一个是key第二个是value

3. 类对象类型注解

# 类对象类型注解
class Student:
    pass

stu: Student = Student()

4. 函数形参和返回值的类型注解

函数和方法的形参类型注解语法:


def 函数名(形参1: 类型, 形参2: 类型, ..., 形参n: 类型):
  pass
# 函数形参的类型注解
def add(x: int, y: int):
    return x + y

返回值注解

语法:

def 函数名(形参1: 类型, 形参2: 类型, ..., 形参n: 类型) -> 返回值类型:
  pass
# 函数形参和返回值的类型注解
def fnuc(data: list) -> list:
    return data

除了使用 变量: 类型, 这种语法做注解外,也可以在注释中进行类型注解。


语法:# type: 类型

# 在注释中进行类型注解
var_1: random.randint(1, 10)  # type: int
var_2: json.loads('{"name": "张三"}')  # type: dict

5. Union类型联合类型注解

Union 类型用于指定一个变量可以是多种类型中的一种。

Union联合类型注解,在变量注解、函数(方法)形参和返回值注解中,均可使用。


Union的使用方式

导包:from typing import Union

语法:Union[类型, …, 类型]

# 使用Union类型,必须先导包
from typing import Union

my_list: list[Union[int, str, dict]] = [1, 2, 'name', {"age": 18}]
my_dict: dict[str, Union[int, str, list]] = {"name": "张三", "age": 18, "grade": [98, 97]}
my_list1: list[Union[int, str, dict[Union[str, int]]]] = [1, 2, 'name', {"age": 18}]

# 函数的Union类型
def func(data: Union[int, str]) -> Union[int, str]:
    return data


相关文章
|
Java
面向对象编程的三大特征:封装;继承;多态
面向对象编程的三大特征:封装;继承;多态
56 0
|
3月前
|
Python
面向对象详解,面向对象的三大特征:封装、继承、多态-1
面向对象详解,面向对象的三大特征:封装、继承、多态
|
3月前
|
安全
面向对象特征(抽象、封装、继承、多态)的具体用法
面向对象特征(抽象、封装、继承、多态)的具体用法
19 0
|
3月前
面向对象三大特征——封装,继承
面向对象三大特征——封装,继承
|
算法 Java 编译器
类和面向对象
类和面向对象
94 0
|
4月前
|
编译器 C++
[C++] 面向对象的三大特性:封装、继承和多态
[C++] 面向对象的三大特性:封装、继承和多态
67 0
|
设计模式 数据安全/隐私保护
面向对象编程基础:封装、继承、多态与抽象的全面解析
面向对象编程基础:封装、继承、多态与抽象的全面解析
77 0
|
存储 数据安全/隐私保护 Python
面向对象编程(OOP):理解类、封装性的关键概念
面向对象编程(OOP):理解类、封装性的关键概念
135 0
浅谈 面向对象三大特性:封装 继承 多态
浅谈 面向对象三大特性:封装 继承 多态
81 0
|
Java 数据安全/隐私保护
14 java面向对象的三大特征【继承、封装、多态】
封装的实现: 实现三部曲: ①私有化,属性 ②提供公共的getXxx()方法 ②提供公共的setXxx()方法
113 0