zoukankan      html  css  js  c++  java
  • 面向對象深入

    封裝
    封裝是將類中的屬性或方法對外部隱藏,對外部提供接口用來輸出想要展示的信息
    不封裝的情況下直接將類中的屬性展示出來,可以被隨意修改。但是封裝之後對外界只提供接口來輸出

    數據,提高了安全性。

    首先可以對屬性進行封裝

    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("密码错误!")

    對方法也可以進行封裝

    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
    当然通过变形后的名字可以直接访问被隐藏的属性  但通过不应该这么做
    变形仅在类的定义阶段发生一次 后续再添加的带有双下划线的任何属性都不会变形  就是普通属性

    property的另一種使用場景
    一個屬性他得值不是固定的,而是通過運算動態產生的

    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 不支持自定义.....")

    多態

    多態指的是不同類型對象可以相應同一種方法而產生不同效果

    鴨子類型就是典型的多態,多種不同的類型使用方法一樣

    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("侧躺着睡!")

    常用的内置函數
    __str__

    使用:如:
    class Car:
        def __init__(self, newWheelNum, newColor):
            self.wheelNum = newWheelNum
               self.color = newColor    
        def __str__(self):
            msg = "嘿。。。我的颜色是" + self.color + "我有" + int(self.wheelNum) + "个轮胎..."
            return msg
        def move(self):
            print('车在跑,目标:夏威夷')
    BMW = Car(4, "白色")
    #嘿。。。我的颜色是白色我有4个轮胎...

    在python中方法名如果是__xxxx__()的,那么就有特殊的功能,因此叫做“魔法”方法

    当使用print输出对象的时候,只要自己定义了__str__(self)方法,那么就会打印从在这个方法中return的数据

    __del__

    当对象被删除前会自动调用 该方法
    声明时候会删除对象?
        1.程序运行结束 解释器退出 将自动删除所有数据
        2.手动调用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()

    反射
    反射是通過字符串來操作對象屬性

    1.hasattr(object, name):可以查看前面的元素是否拥有后面的元素,后面的元素要用引号包裹,前面不需要。

    但是这里必须要实例化,如果是hasattr(Foo,‘name’)报False.

    2.getattr(object, name[, default]):   根据括号的元素拿到相应的值,getattr(l1,l2),也就是如果后面的元素属于前面,那么会取出l1.l2的值。如果不是那就报错。

    如果getattr(l1,'l2')尾部再加上'加上某些东西',例:gerattr(l1,'l2','l3'),如果是错误了那么会显示最后双引号里面的东西,也就是l3,如果是正确则不会显示,只会显示正确的答案。

    class Base():
        def __init__(self,name,id):
            self.id=id
            self.name=name
    
    
        def show(self):
            print('id:%s,name:%s'%(self.id,self.name))

    b1=Base('aaa',12)
    print(getattr(b1,'name'))

    ==》aaa



    3.setattr(object, name, value) :给object对象的name属性赋值value,如果对象原本存在给定的属性name,则setattr会更改属性的值为给定的value;如果对象原本不存在属性name,setattr会在对象中创建属性,并赋值为给定的value;



    4.delattr(object, name)  :  函数作用用来删除指定对象的指定名称的属性,和setattr函数作用相反。

    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 即导入成功的模块

    补充

    __getattr__:当对象获取自己没有的属性的时候自动触发
    __setattr__:当对象想要给某个属性赋值时,如” user.id=11“

  • 相关阅读:
    每日一水 POJ8道水题
    编译和使用 MySQL C++ Connector
    j2ee model1模型完成分页逻辑的实现 详解!
    DB查询分析器访问EXCEL时,要在表名前后加上中括弧或双引号
    指向结构体变量的指针
    EOSS V3.0 企业运营支撑系统(基于RBAC原理的权限管理)
    MybatisGen1.0 Mybatis JavaBean Mapper生成工具
    The table name must be enclosed in double quotation marks or sqare bracket while accessing EXCEL by
    资源-Android:Android
    软件-开发软件:Android Studio
  • 原文地址:https://www.cnblogs.com/duGD/p/10896910.html
Copyright © 2011-2022 走看看