• Python3 面向对象进阶1


    组合

    概念

    • 组合指的是一个对象中的属性是另一个对象

    目的

    • 组合的目的和继承一样, 为了减少代码冗余

    实现方式

    # 1
    class Other:
        def func(self):
            print('from other')
    
    
    class Foo:
        def __init__(self):
            self.other = other()
            
         def func(self):
            self.other.func()
            
    foo = Foo()
    foo.func()  # from other
                  
    
    # 2
    class Other:
        def func(self):
            print('from other')
            
    
    class Foo:
        pass
    
    foo = Foo()
    other_obj = Other()
    
    foo.func = other_obj.func
    foo.func()  # from other
            
    
    • 总结:
      1. 继承: 是一种xx是xx的关系(is-a)
      2. 组合: 是一种xx有xx的关系(has-a)

    封装

    概念

    • 封装指的是把一系列属性(特征和技能)放到一个类中就构成了封装

    • 存数据的目的是为了取, 对象可以通过.的方式获取属性

    目的

    • 封装的目的是方便取用, 对象可以通过对象.属性的方式获取属性

    实现方式

    • 定义类时, 把一系列属性(特征和技能)放到一个类中就构成了封装

    访问限制

    概念

    • 在类内部, 凡是以__开头的属性都会被隐藏起来, 外部不能直接访问

    目的

    • 对重要或隐私数据获取的更加严谨, 进而保证了数据的安全
    • 隐私属性可以通过在类内部封装一个接口, 在接口内做业务逻辑处理, 再把数据返回给调用者
    • 注意: 在Python中, 不会强制限制属性的访问, 类内部__开头的属性, 只是做了一种变形, 若想访问, 调用变形后的名字即可
    class Foo:
        __name = 'bigb'
        
        def __func(self):
            print('secret')
    
    
    foo = Foo()
    
    print(foo._Foo__name)  # bigb
    foo._Foo__func()  # secret
    

    实现方式

    # 1
    class PyMan:
        language = 'Python'
    
        def __init__(self, name, age, gender):
            self.__name = name
            self.__age = age
            self.__gender = gender
    
        # 打印用户信息接口
        def get_info(self):
            username = input('请输入用户名: ')
            password = input('请输入密码: ')
    
            if username == 'bigb' and password == '123':
                print(f'''
                姓名: {self.__name}
                年龄: {self.__age}
                性别: {self.__gender}
                ''')
    
        # 修改用户信息接口
        def set_info(self, name, age, gender):
            if not isinstance(name, str):
                raise TypeError
            if not isinstance(age, int):
                raise TypeError
            if not isinstance(gender, str):
                raise TypeError
    
            self.__name = name
            self.__age = age
            self.__gender = gender
    
    
    bigb = PyMan('bigb', 18, 'male')
    bigb.get_info()  
    bigb.set_info()
     
    
    # 2
    class ATM:
    
        def __insert_card(self):
            print('插卡')
    
        def __input_pwd(self):
            print('输入密码')
    
        def __input_money(self):
            print('输入金额')
    
        def __get_monet(self):
            print('执行吐钱')
    
        def __print_bill(self):
            print('打印账单')
    
        def withdraw(self):
            self.__insert_card()
            self.__input_pwd()
            self.__input_money()
            self.__get_monet()
            self.__print_bill()
            print('取款程序执行完毕!')
    
    
    
    atm = ATM()
    atm.withdraw()
    
    '''
    插卡
    输入密码
    输入金额
    执行吐钱
    打印账单
    取款程序执行完毕!
    '''
    

    property

    概念

    • Python内置的装饰器, 主要给类内部的方法使用

    目的

    • 是将类内部的方法def 方法名():变成了def 方法:
    • 在对象调用某个方法时, 将对象.方法名()变成对象.方法名, 使其看起来像一个普通的数据属性

    实现方式

    @property

    class People:
        def __init__(self, name, weight, height):
            self.name = name
            self.weight = weight
            self.height = height
    
        @property
        def bmi(self):
            return self.weight / (self.height * self.height)
    
    
    bigb = People('bigb', 70, 1.8)
    
    # 如果不用@property, 则print(bigb.bmi())
    print(bigb.bmi)
    

    多态

    概念

    • 不同的子类对象调用相同的父类方法, 产生不同的执行结果

    • 继承重新父类方法为前提

    • 是调用方法的技巧, 不会影响类的内部设计

    目的

    • 多态可以增加代码的灵活度

    抽象类

    概念

    • abc 模块

    目的

    • 强制在定义子类时必须定义和父类的相同的方法

    实现方法

    import abc

    import abc
    
    
    class Animal(metaclass=abc.ABCMeta):
        @abc.abstractmethod
        def eat(self):
            pass
    
        @abc.abstractmethod
        def drink(self):
            pass
    
    
    class Pig(Animal):
        def eat(self):
            print('pig is eating...')
    
    
    peppa = Pig()
    
    

    TypeError: Can't instantiate abstract class Pig with abstract methods drink

    父类方法被 @abc.abstractmethod装饰后, 子类必须也有相同的方法, 否则会报错

    鸭子类型

    • 当看到一只鸟走起来像鸭子、游泳起来像鸭子、叫起来也像鸭子,那么这只鸟就可以被称为鸭子
    • 不关注类型, 只关注方法
    • 继承: 耦合度高, 程序的可扩展性差
    • 鸭子类型: 程序的可扩展性强
  • 相关阅读:
    我画着图,FluentAPI 她自己就生成了
    寻找性能更优秀的不可变小字典
    寻找性能更优秀的动态 Getter 和 Setter 方案
    数据治理方案技术调研 Atlas VS Datahub VS Amundsen
    数据库读写分离这个坑,你应该踩过吧?
    写了一套优雅接口之后,领导让我给大家讲讲这背后的技术原理
    年轻人不讲武德,竟然重构出这么优雅后台 API 接口
    贞炸了!上线之后,消息收不到了!
    一笔订单,但是误付了两笔钱!这种重复付款异常到底该如何解决?
    自动化运维工具之Puppet master/agent模型、站点清单和puppet多环境设定
  • 原文地址:https://www.cnblogs.com/bigb/p/11656368.html
Copyright © 2020-2023  润新知