• 组合 封装 多态


    一.组合

    1.什么是组合

      一个对象的属性是来自另一外一个类的对象,称之为组合

    2.为何用组合

      组合也是用来解决类与代码冗余的问题

    3.如何用组合

    class Foo:
        aaa=1111
        def __init__(self,x,y)
            self.x=x
            self.y=y
    
        def func1(self):
            print('Foo内的功能')
    
    class Bar:
        bbb=2222
        def __init__(self,m,n):
            self.m = m
            self.n = n
    
        def func2(self):
            print('Bar内的功能')
    obj1=Foo(10,20)
    obj2=Bar(30,40)
    
    obj1.xxx=obj2
    print(obj1.x,obj1.y,obj1.aaa,obj1.func1)
    
    print(obj1.xxx.m,obj1.xxx.n,obj1.xxx.bbb,obj1.xxx.func2)

    组合另一个类中的多个对象

    class OldboyPeple:
        school = 'Oldboy'
        def __init__(self,name,age,gender):
            self.name = name
            self.age = age
            self.gender = gender
    
    class OldboyStudent(OldboyPleople):
        def choose_course(self):
            print('%s is choosing course'%self.name)
    
    class OldboyTeacher(OldboyPeople):
        def choose_course(self):
            stu,num=num
            print('老师%s给学生%s打分%s'%(self.name,stu.name,num))
    
    class Course:
        def __init__(self,course_name,course_price,course_period):
            self.course_name = course_name
            self.course_price=course_price
            self.course_period=course_period
    
        def tell_course(self):
            print('课程名:<%s>价格:[%s] 周期:[%s]%(self.course_name,self.course_price,self.course_period))
    
    python_obj = Course('python开发',3000,'5mons')
    linux_obj=Course('linux运维',5000,'3mons')
    
    stu1=OldboyStudent('egon',18,'male')
    stu1.course=[]
    stu1.courses.append(linux_obj)
    stu1.courses.append(python)obj)
    stu1.courses[0].tell_course()

    二.封装

    1.什么是封装

      装指的是吧属性装进一个容器

      封指的是隐藏的意思,但是这种隐藏式对外不内的

    2.为何要封装

      封装不是单纯意义的隐藏

      封装数据属性的目的:将数据属性封装起来,类外的使用就无法直接操作该数据属性了

      需要内部开一个接口给使用者,类的实际者可以在接口上附带任何逻辑,从而严格

      控制使用者对属性的操作

      封装函数属性的目的:隔离复杂度

    3.如何封装

      只要在属性前加上__开头,该属性就会被隐藏起来,该隐藏具备的特点:

        1.只要一种语法意义上的变形,即__开头的属性会在检测语法时发生变形,_类名__属性名.

        2.这种隐藏是对外不对内的,因为在类内部检测语法时所有的代码统一都会发生变形

        3.这种变形值在检测时发生一次,在类定义之后新增的__开头的属性并不会发生变形

        4.如果父类不想让子类覆盖自己的属性,可以在属性前加__开头.

    #其实这仅仅这是一种变形操作且仅仅只在类定义阶段发生变形
    #类中所有双下划线开头的名称如__x都会在类定义时自动变形成:_类名__x的形式:
    
    class A:
        __N=0 #类的数据属性就应该是共享的,但是语法上是可以把类的数据属性设置成私有的如__N,会变形为_A__N
        def __init__(self):
            self.__X=10 #变形为self._A__X
        def __foo(self): #变形为_A__foo
            print('from A')
        def bar(self):
            self.__foo() #只有在类内部才可以通过__foo的形式访问到.
    
    #A._A__N是可以访问到的,
    #这种,在外部是无法通过__x这个名字访问到。

    内部调用

    class ATM:
        def __card(self):
            print('插卡')
        def __auth(self):
            print('用户认证')
        def __input(self):
            print('输入取款金额')
        def __print_bill(self):
            print('打印账单')
        def __take_money(self):
            print('取款')
    
        def withdraw(self):
            self.__card()
            self.__auth()
            self.__input()
            self.__print_bill()
            self.__take_money()
    
    a=ATM()
    a.__card(self)
    a.withdraw()

    隐藏的属性可以被内部使用

    class ATM:
        def __card(self):
            print('插卡')
        def __auth(self):
            print('用户认证')
        def __input(self):
            print('输入取款金额')
        def __print_bill(self):
            print('打印账单')
        def __take_money(self):
            print('取款')
    
        def withdraw(self):
            self.__card()
            self.__auth()
            self.__input()
            self.__print_bill()
            self.__take_money()
    
    a=ATM()
    a.__card(self)
    a.withdraw()

    三.property装饰器.

    property是一种特殊的属性,访问它时会执行一段功能(函数)然后返回值

      即:可以把函数结果作为属性被返回.

    例一:BMI指数(bmi是计算而来,但很明显它听起来是一个属性而非方法,如果我们将其做成一个属性,更便于理解)

    成人的BMI数值:

    过轻:低于18.5

    正常:18.5-23.9

    过重:24-27

    肥胖:28-32

    非常肥胖:高于32

      体质指数(BMI)=体重(kg)➗身高²(m)

      EX:70kg ➗(1.75✖️1.75) = 22.86

    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 ** 2)
    
    obj=People('egon',70,1.82)
    obj.height=1.85
    
    print(obj.bmi)

    property的需要了解的用法

    class People:
        def __init__(self,name)
            self.__name=name
    
        @property
        def name(self)
            return'<name:%s>self.name
    
        @name.setter
        def name(self,new_name):
            if type(new_name)is not str:
                print('名字必须是str类型")
                return
            self.__name=new_name
        
        @name.deleter
        def name(self)
            del self.name
    obj=People('egon')
    print(obj.name)
    
    obj.name=123
    print(obj.name)
    
    def obj.name
    print(obj.__dict__)

    四.多态,

    1.什么是多态

      同一事物的多种形态

    2.为何要用多态

      多态性:指

    import abc
    
    class Animal(metaclass=abc.ABCMeta):
        @abc.abstractmethod
        def speak(self):
            pass
    
    # Animal() # 父类不能实例化,因为父类本身就是用来制定标准的
    class People(Animal):
        def speak(self):
            print('say hello')
        # def jiao(self):
        #     print('say hello')
    
    class Dog(Animal):
        def speak(self):
            print('汪汪汪')
    
    class Pig(Animal):
        def speak(self):
            print('哼哼哼')
    
    
    peo=People()
    dog1=Dog()
    pig1=Pig()
    #
    #
    peo.speak()
    dog1.speak()
    pig1.speak()
    def speak(animal):
        animal.speak()
    
    speak(peo)
    speak(dog1)
    speak(pig1)
  • 相关阅读:
    三、单例模式
    二、工厂模式
    一、设计模式六大原则
    十二、Spring之IOC容器初始化
    PythonWeb开发教程(二),搭建第一个django项目
    PythonWeb开发教程(一),开发之前需要准备什么
    基于python的性能测试工具–locust
    在成为测试大牛的路上,我推荐BestTest
    移动端自动化测试(一)appium环境搭建
    常用工具篇(二)死链接扫描工具–Xenu
  • 原文地址:https://www.cnblogs.com/gongcheng-/p/9845919.html
Copyright © 2020-2023  润新知