第二十四章:封装,多态,继承

it2025-10-29  13

封装

什么是封装 what

对外部隐藏内部的属性,以及实现细节  , 给外部提供使用的接口

注意:封装有隐藏的意思,但不是单纯的隐藏

学习封装的目的.就是为了能够限制外界对内部数据的访问

python中属性的权限分为两种

1.公开的

没有任何限制 谁都能访问

2.私有的

只有当前类本身能够访问

默认为公共的

 

如何封装 how

.................

为什么要封装 why

1.提高安全性 

封装属性

2.隔离复杂度

封装方法

 

 

 

一个类中分为两种数据,属性和方法

封装属性:

class Student:​    def __init__(self,name,age,gender,id_card):        self.name = name        self.age = age        self.gender = gender        self.__id_card = id_card​    def show_id_card(self):        # 可以在这里添加额外的任何逻辑代码 来限制外部的访问                #在类的内部 可以访问        print(self.__id_card)

对私有属性的访问以及修改

class Student:    def __init__(self,name,age,gender,id_card):        self.name = name        self.age = age        self.gender = gender        self.__id_card = id_card​    # 访问被封装的属性 称之为访问器    def get_id_card(self,pwd):        # 可以在这里添加额外的任何逻辑代码 来限制外部的访问        # 在类的内部 可以访问        if pwd =="123":            return self.__id_card        raise Exception("密码错误!")​​    # 修改被封装的属性   称之为设置器    def set_id_crad(self,new_id):        # 身份证必须是字符串类型        # 长度必须是18位        if isinstance(new_id,str) and len(new_id) == 18:            self.__id_card = new_id        else:            raise Exception("身份证号码 必须是字符串 且长度必须为18!")

什么样的方法应该被封装起来

一个为内部提供支持的方法,不应该让外界直接访问,那就封装起来 ,如下例中的 user_auth等...

class ATM:​    def withdraw(self):        self.__user_auth()        self.__input_money()        self.__save_record()        # 输入账号和密码        # 显示余额        # 输入取款金额        # 保存记录​    def __user_auth(self):        print("请输入账号密码....")​    def __input_money(self):        print("余额为100000000,请输入取款金额!")​    def  __save_record(self):        print("记录流水....")

封装的原理:

python是通过 变形的方式来实现的封装如何变形 在名称带有双下划线开头的变量名字前添加_类名 如_Person__id_card当然通过变形后的名字可以直接访问被隐藏的属性 但通过不应该这么做变形仅在类的定义阶段发生一次 后续再添加的带有双下划线的任何属性都不会变形 就是普通属性

 

什么时候用   where

封装属性  

当这个对象存在一个机密性的属性  例如 人的身份证 银行卡密码等等,这样属性不应该被外界直接 访问当 ,那就封装起来

Person  密码    Teacher  工资   

封装方法  

一个为内部提供支持的方法,不应该让外界直接访问,那就封装起来 ,如下例中的 user_auth等..

 

Property

作用: 将一个方法伪装成普通属性

为什么用 property    希望将访问私有属性和普通属性的方式变得一致

与property相关的 两个装饰器

setter

用点语法 给属性赋值时触发  

deleter

用点语法删除属性时触发

案例:

class Teacher:    def __init__(self,name,age,salary):        self.name = name        self.age = age        self.__salary = salary​    @property  # getter   # 用于访问私有属性的值   也可以访问普通属性    def salary(self):        return self.__salary​    @salary.setter   # 用来设置私有属性的值 也可以设置普通属性    def salary(self,new_salary):        self.__salary = new_salary​    @salary.deleter # 用来设置私有属性的值 也可以删除普通属性    def salary(self):        # print("can not delete salary!")        del self.__dict__["_Teacher__salary"]

 

property的另一种使用场景  计算属性

什么是计算属性   一个属性 它的值不是固定死的 而是通过计算动态产生的BMI

class Person:    def __init__(self,name,height,weight):        self.name = name        self.height = height        self.weight = weight        # self.BMI = weight / (height ** 2)​    @property    def BMI(self):        return self.weight / (self.height ** 2)​    @BMI.setter    def BMI(self,new_BMI):        print("BMI 不支持自定义.....")​​p = Person("egon",1.7,80)print(p.BMI)p.BMI = 10

多态 :

多态不是一个具体的技术  或代码

指的是 多个不同类型对象 可以响应同一个方法 ,产生不同结果 

多态某种事物具备多个不同形态例如 水:   气态 固态 液态     动物: 人 猫 猪     汽车人: 汽车 飞机 人型​OOP中 标准解释: 多个不同类型对象 可以响应同一个方法 并且产生不同结果​多态的带来的好处:   只需要学习基类中的使用方法即可, 不需要关心具体的哪一个类 以及实现的   以不变应万变   提高了灵活性   提高扩展性       如果没有多态 需要分别学习 person cat pig 的不同使用方法 这对于使用者而言太麻烦了​如何实现多态: 鸭子类型 就是典型的多态 多种不同类型 使用方法一样

案例:

class Cat():    def bark(self):        print("喵喵喵")    def run(self):        print("四条腿跑!")    def sleep(self):        print("趴着睡!")        class Pig():    def bark(self):        print("哼哼哼!")    def run(self):        print("四条腿跑!")    def sleep(self):        print("侧躺着睡!")​# 一个用来管理动物的方法   只要你传入是一个动物 我就按照动物的标准来使用 完全不用考虑你具体是什么类型def management_animal(animal):    print("==================正在溜%s=============" % animal.__class__.__name__)    animal.bark()    animal.run()    animal.sleep()

 

封装   

什么是封装  *****

封装的好处  *****

如何封装

封装的原理

property    *****

setter  deleter  

计算属性

多态: 

多态指的是 多个不同类型对象可以响应同一个方法产生不同的结果   *****

好处 *****

好处:     只需要学习基类中的使用方法即可, 不需要关心具体的哪一个类 以及实现的   以不变应万变   提高了灵活性提高扩展性 ​如果没有多态 需要分别学习 person cat pig 的不同使用方法 这对于使用者而言太麻烦了

如何实现多态  鸭子类型 

 

 

 

 

 

常用的内置函数

 

__str__

 

__del__

"""__del__当对象被删除前会自动调用 该方法声明时候会删除对象?   1.程序运行结束 解释器退出 将自动删除所有数据   2.手动调用del 时也会删除对象​注意:该函数不是用来删除对象的​使用场景当你的对象在创建时,开启了不属于解释器的资源 例如打开了一个文件必须保证当对象被删除时 同时关闭额外的资源 如文件​​也称之为析构函数 构造 的反义词   构造 指的是从无到有   析构 值从有到无   简单的说就对象所有数据全部删除​​总结:__del__该函数 用于 在对象删除前做一些清理操作"""# 假设要求每一个person对象都要绑定一个文件class Person:    def __init__(self,name,path,mode="rt",encoding="utf-8"):        self.name = name        self.file = open(path,mode,encoding=encoding)​​​    # 读取数据的方法    def read_data(self):        return self.file.read()​​    def __del__(self):        print("del run!")        self.file.close()

 

反射

英文中叫反省 (自省)  

面向对象中的反省 指的是,一个对象必须具备,发现自身属性,以及修改自身属性的能力;  

一个对象在设计初期,可能考虑不够周全后期需要删除或修改已经存在的属性, 和增加属性

反射就是通过字符串来操作对象属性

 

 

涉及到的方法:

hasattr 判断是否存在某个属性​getattr 获取某个属性的值​setattr 新增或修改某个属性 ​delattr 删除某个属性

案例:

class MY_CMD:​    def dir(self):        os.system("dir")​    def ipconfig(self):        os.system("ipconfig")​cmd = MY_CMD()​while True:    name = input("请输入要执行的功能:")    if hasattr(cmd,name):        method = getattr(cmd,name)        print(method)        method()    else:        print("sorry this method is not exists....!")

 

动态导入模块

"""直接写import 称之为静态导入 建立在一个基础上:提前已经知道有这个模块 动态导入 指的是 在需要的任何时候 通过指定字符串类型的包名称来导入需要的模块 import importlibmk = importlib.import_module(m_name)mk 即导入成功的模块"""该方式常用在框架中 因为框架设计者不可能提前预知后续需要的模块和类

 

 

 

 

 

 

 

转载于:https://www.cnblogs.com/haojunliancheng/p/10896381.html

最新回复(0)