zoukankan      html  css  js  c++  java
  • day26

    今日所学:

    封装

    什么是封装

    对外部隐藏内部的属性,以及实现细节,给外部提供使用的接口。       注意:封装有隐藏的意思,但不是单纯的隐藏

    为什么封装

    1,提高安全性。2,隔离复杂度

    学习封装的目的,就是为了能够限制外界对内部的数据的访问。python中属性的权限有两种:

           1》公开的:没有 任何限制,谁都能访问

            2》私有的:只有当前类本身可以用

    # 案例:怎样进行封装
    class Student:
        def __init__(self,name,age,gender,id_card):
            self.name = name
            self.age = age
            self.gender = gender
            self.__id_car = id_card
        def show_id_card(self):               #进行封装,访问一个私有被封装的方法
            # 可以在这里添加额外的任何逻辑代码,来限制外部的访问
            print(self.__id_card)                #完成封装 封装的方法
    stu1 = Student("rose",20,",man","1111111111111111111")
    print(stu1.name)         #结果为 rose
    # print(stu1.__id_card)      #这样访问不了id_card ,报错
    print(Student.__id_card)       #这样可以访问,结果为rose,即只有当前类本身能够访问
    stu1.show_id_card()              #结果为 rose
    # ##########
    # 封装属性:提现了安全性
    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):               #进行封装,访问一个私有被封装的方法
            # 可以在这里添加额外的任何逻辑代码,来限制外部的访问
            print(self.__id_card)
            return self.__id_card
            #修改被封装的属性         称之为设置器
        def set_id_card(self,new_id):         #从外界传入一个新的值
            #案例:身份证号码必须是字符串类型,长度必须是18位
            if isinstance(new_id, str) and len(new_id) ==18:
                self.__id_card = new_id
            else:
                print("身份证号码错误,必须是字符串,且长度必须为18")
            self.__id_car = new_id
    stu1 = Student("rose", 20, ",man", "1111111111111111111")
    stu1.show_id_card()
    # stu1.set_id_card("22222222222222")
    # stu1.show_id_card()
    id = stu1.get_id_card()
    print(id)
    stu1.set_id_card(123)       #结果为:身份证号码错误,必须是字符串,且长度必须为18
    stu1.set_id_card("123456789987654321")
    print(stu1.get_id_card())          #结果为123456789987654321
    #     总结:在set_id_card中可以增加限制,和满足你所需求的功能,对其封装的进行修改
    #           同理。在get_id_card中也可以怎加限制,例如判断满足的条件,判断合法就访问,对其用户进行了限制
    #           目的:是为了保证安全性。除了可以封装属性,还可以封装方法
    # 封装方法:体现了隔离复杂度
    class ATM:
        def withdraw(self):
            self.__user_auth()
            self.__input_money()
            self.__save_record()
        def __user_auth(self):
            print("请输入账号密码...")
        def __input_money(self):
            print('请输入取款金额,余额为10000元')
        def __save_record(self):
            print("记录流水")
    atm = ATM()
    atm.withdraw()
    #     总结:1,什么样的方法应该被封装起来:
    #            一个为内部提供支持方法,不应该让外界直接访问,就把它藏起来,如上例中的__user_auth
    #如何封装的:封装原理
    #    就是把名字做了修改,通过修改名字的方法,即变形
    #    如何变形,就是在名称带有双下划线开头的变量名字前加了_类名  如_Person_id_card
    #    注意:变形这个操作是在定义类的时候发生的,只发生一次,
    #          后续再添加的带有双下划线的任何属性,都将不会变形
    #什么时候应该封装属性:
    #      如银行卡密码,这种属性就不能直接被外界使用,要封装起来
    class Teacher:
        def __init__(self, name, age, salary):
            self.name = name
            self.age = age
            self.__salary = salary
        @property
        def get_salary(self):
            return self.__salary
        def set_salary(self, new_salary):
            self.__salary = new_salary
    t =Teacher("fee",23,16000)
    print(t.get_salary())
    t.set_salary(20000)
    print(t.get_salary())
    print(t.name)
    #   出现的问题:被封装的属性在访问时,需要调用方法,而普通属性直接点就ok
    #              这样一来对于使用者而言,必须要知道访问的属性,是私有还是公开,
    #             然后调用对象的方法比较麻烦的。此时,我们的目标是,让访问的私有属性
    #              和访问普通属性的方式一致,这时候就需要property装饰器,就是将一个私有的伪装成共有的
    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, a):
            print(a)
    t = Teacher("WWW",22,11111)
    t.salary = 500
    print(t.salary)
    print(t.__dict__)
     #通常使用 @property来访问私有的,希望将私有属性变为普通属性访问

    多态:

    标准解释:多个不同类型对象,可以响应同一个方法,并且产生不同结果

    1.增加了程序的灵活性

      以不变应万变,不论对象千变万化,使用者都是同一种形式去调用,如func(animal)

    2.增加了程序额可扩展性

      通过继承animal类创建了一个新的类,使用者无需更改自己的代码,还是用func(animal)去调用  

    比如:老师.下课铃响了(),学生.下课铃响了(),老师执行的是下班操作,学生执行的是放学操作,虽然二者消息一样,但是执行的效果不同

    import abcclass Animal(metaclass=abc.ABCMeta): #同一类事物:动物    @abc.abstractmethod    def talk(self):        pass

    class People(Animal): #动物的形态之一:人    def talk(self):        print('say hello')

    class Dog(Animal): #动物的形态之二:狗    def talk(self):        print('say wangwang')

    class Pig(Animal): #动物的形态之三:猪    def talk(self):        print('say aoao')

    常用的内置函数

    # 类中的内置函数:
    # 1__str__
    class Person:
        # 将对象转成字符串的时候执行
        def __str__(self):
            print("str run")
            return "ffff"
    p = Person()
    # str(p)                  str run
    # 在默认的object 中,不要方法也可以实现,可以自己定义,去覆盖原来的定义,想要实现自己的功能
    # 再打印时,通过自定义的效果,返回值必须是字符串类型,该方法在object 中,子类可以覆盖该方法来进行自定义

    反射

    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 importlib
    mk = importlib.import_module(m_name)
    mk 即导入成功的模块
    """
    该方式常用在框架中 因为框架设计者不可能提前预知后续需要的模块和类

     

  • 相关阅读:
    java 模拟http请求,通过流(stream)的方式,发送json数据和文件
    $listeners 在vue中的使用 --初学
    vue中关于checkbox数据绑定v-model指令说明
    Vue--理解非prop特性
    Vue里标签嵌套限制问题解决------解析DOM模板时注意事项:
    vue click.stop
    @click.prevent.self和@click.self.prevent区别
    assign()-JS
    摘抄大神对VUE 中slot-scope的深度理解
    oracle11G备份空表解决办法
  • 原文地址:https://www.cnblogs.com/Fzhiyuan/p/10897079.html
Copyright © 2011-2022 走看看