zoukankan      html  css  js  c++  java
  • Day 21 组合/封装/property特性/多态和多态性/抽象类/鸭子类型

    组合

    什么是组合

    组合就是一个类的对象具备某一个属性,该属性的值是指向另外一个类的对象

    为什么要使用组合

    为了减少类与类之间代码的冗余

    如何使用组合

    class Course:
        def __init__(self, course_name, course_period):
            self.course_name = course_name
            self.course_period = course_period
    
        def tell_info(self):
            print(f'''
                课程信息
                课程名称:{self.course_name}
                课程时长:{self.course_period}
            ''')
    
    
    class Student:
        def __init__(self, name, age, gender):
            self.name = name
            self.age = age
            self.gender = gender
            self.course_list = []
    
        def choose_course(self, course_obj):
            self.course_list.append(course_obj)
    
        def tell_course_info(self):
            for course in self.course_list:
                course.tell_info()
    
    # 创建课程和学生对象
    python = Course('python', '6个月')
    stu = Student('Tiny', 18, 'male')
    
    #添加课程
    stu.choose_course(python)
    # 获取课程信息
    stu.tell_course_info()
    

    封装

    什么是封装

    封装指的是将一堆属性(特征和技能)放到一个对象中

    为什么要封装

    1. 封装数据的原因:保护隐私
    2. 封装方法的原因:隔离复杂度

    两个层面的封装

    封装其实分为两个层面,但无论哪种封装,都要对外界提供好访问你内部隐藏内容的接口(接口可以理解为入口,有了这个入口,使用者无需且不能够直接访问到内部隐藏的细节,只能走接口,并且我们可以在接口的实现上附加更多的处理逻辑,从而严格控制使用者的访问)

    第一个层面的封装

    创建类和对象会分别创建二者的名称空间,我们可以用类名.或者对象.的方式去访问里面的名字,这本身就是一种封装

    注意:对于这一层面的封装,类名.和对象名.就是访问隐藏属性的接口

    第二个层面的封装

    类中把某些属性和方法隐藏起来(或者说定义成私有),只有类的内部使用,外部无法访问,或者留下少量接口(函数)供外部使用

    在python中用__(双下划线)的方式来实现隐藏属性(私有化)

    类中所有双下划线开头的名称如__x都会自动变成:_类名__x的形式:

    class A:
        __name = 'Tiny'
    
        def __foo(self):
            print('from A')
    
        def get_name(self):
            return self.__name
    
        def set_name(self):
            self.__name = 'Nick'
    
    
    a = A()
    print(a.get_name())
    a.set_name()
    print(a.get_name())
    print(a._A__name)
    
    Tiny
    Nick
    Nick
    

    这种自动变形的特点:

    1. 类中定义的__name只能在类中使用,如self.__name
    2. 这种变形其实正是针对内部的变形,在外部是无法通过__name这个名字访问到的
    3. 在子类定义的__name不会覆盖在父类定义的__name,因为子类中变形成了_子类名__name,而父类中变形成了_父类名__name,即双下划线开头的属性在继承给子类时,子类是无法覆盖的

    注意:对于这一层面的封装,我们需要在类中定义一个函数(接口函数)在它内部访问被隐藏的属性,然后外部就可以使用了

    这种变形需要注意的问题是:

    1. 这种机制也并没有真正意义上限制我们从外部直接访问,知道了类名和属性名就可以拼出名字,_类名__属性名,然后就可以访问了
    2. 变形的过程只在类的定义时发生一次,在定义后的赋值操作,不会变形
    3. 在继承中,父类如果不想让子类覆盖自己的方法,可以将方法定义为私有的

    类的property特性

    什么是property特性

    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)
    
        @property
        def get_name(self):
            return self.name
    
        @get_name.setter
        def set_name(self, val):
            self.name = val
    
    
    people = People('tiny', 54, 1.7)
    print(people.bmi)
    people.set_name = 'jack'
    print(people.get_name)
    

    property属性的定义和调用要注意以下几点:

    1. 定义是,在实例方法的基础上添加@property装饰器;并且仅有一个self参数
    2. 调用时,无需括号

    类的多态和多态性

    什么是多态

    多态指的是一类事物有多种形态

    1. 序列数据类型有多种形态:字符串,列表,元组
    2. 动物有多种形态:人,狗,猪

    什么是多态性

    多态性是指具有不同功能的函数可以使用相同的函数名,这样就可以用一个函数名调用不同内容的函数.

    class Pig:
        def run(self):
            print('pig is running')
    
    
    class Dog:
        def run(self):
            print('dog is running')
    
            
    pig = Pig()
    dog = Dog()
    
    pig.run()
    dog.run()
    

    抽象类

    什么是抽象类

    abc模块 abstract_class

    为什么使用抽象类

    强制子类必须遵循父类的一套标准

    如何使用抽象类

    import abc
    
    
    class Animal(metaclass=abc.ABCMeta):
        @abc.abstractmethod
        def run(self):
            pass
    
    
    class Pig(Animal):
        def run(self):
            print('pig is running')
    
    
    class Dog(Animal):
        def run(self):
            print('dog is running')
    
    
    pig = Pig()
    dog = Dog()
    
    pig.run()
    dog.run()
    

    鸭子类型

    什么是鸭子类型

    Duck typing 这个概念来源于美国印第安纳州的诗人詹姆斯·惠特科姆·莱利(James Whitcomb Riley,1849-
    1916)的诗句:”When I see a bird that walks like a duck and swims like a duck and quacks like a duck, I call that bird a duck.”
    在python中,不推荐使用抽象类来强制限制子类的定义,但是推荐都遵循鸭子类型

    继承:

    ​ 耦合性太高,程序的可扩展性差

    鸭子类型:

    ​ 耦合性低,程序的可扩展性强

  • 相关阅读:
    UI: Form editor && use CRectTracker to allow user drag/move/resize graphics
    如何设置共享文件夹
    log4net每天生成一个log文件
    自动属性/匿名方法/Lamda表达式
    ASPOSE.CELL
    转载:动态调用WebService(C#)
    按钮Button动态事件的名称
    ASPOE.WORD
    操作MSSQL服务还有测试是否连接
    操作MSSQL服务还有测试是否连接1
  • 原文地址:https://www.cnblogs.com/2222bai/p/11655187.html
Copyright © 2011-2022 走看看