zoukankan      html  css  js  c++  java
  • 面向对象(三)——组合、多态、封装、property装饰器

    组合、多态、封装、property装饰器

    一、组合

    1、什么是组合

    组合指的是某一个对象拥有一个属性,该属性的值是另外一个类的对象

    1 class Foo():
    2     pass
    3 
    4 class Bar():
    5     pass
    6 
    7 obj=Bar()
    8 obj.attrib=Foo()
    组合

    2、组合的作用

    通过为某一个对象添加属性(属性值是另外一个类的对象)的方式,可以间接地将两个类关联/整合/组合到一起,从而减少类与类之间代码冗余

    3、组合的使用

     1 class OldboyPeople:
     2     school = 'oldboy'
     3 
     4     def __init__(self, name, age, sex):
     5         self.name = name
     6         self.age = age
     7         self.sex = sex
     8 
     9 
    10 class OldboyStudent(OldboyPeople):
    11 
    12     def __init__(self, name, age, sex, score=0):
    13         super().__init__(name, age, sex)
    14         self.score = score
    15         self.courses = []
    16 
    17     def choose_course(self):
    18         print('%s choosing course' % self.name)
    19 
    20     def tell_all_course(self):
    21         print(('学生[%s]的课程如下' % self.name).center(60, '='))
    22         for course in self.courses:
    23             course.tell_course()
    24         print('=' * 80)
    25 
    26 
    27 class OldboyTeacher(OldboyPeople):
    28 
    29     def __init__(self, name, age, sex, level):
    30         super().__init__(name, age, sex)
    31         self.level = level
    32         self.courses = []
    33 
    34     def score(self, stu, num):
    35         stu.score = num
    36 
    37     def tell_all_course(self):
    38         print(('老师[%s]教授的课程如下' % self.name).center(70, '-'))
    39         for course in self.courses:
    40             course.tell_course()
    41         print('-' * 80)
    42 
    43 
    44 class Course:
    45     def __init__(self, c_name, c_price, c_period):
    46         self.c_name = c_name
    47         self.c_price = c_price
    48         self.c_period = c_period
    49 
    50     def tell_course(self):
    51         print('<课程名:%s 价格:%s 时间:%s>' % (self.c_name, self.c_price, self.c_period))
    52 
    53 
    54 python = Course('python全栈开发', 10000, 5)
    55 linux = Course('linux架构', 12000, 5)
    56 
    57 stu = OldboyStudent('zs', 18, 'male')
    58 stu.courses.append(python)
    59 stu.courses.append(linux)
    60 stu.tell_all_course()
    61 
    62 teach = OldboyTeacher('egon', 18, 'male', 10)
    63 teach.courses.append(python)
    64 teach.tell_all_course()
    组合的使用

    二、多态与多态性

    1、什么是多态

    多态指的是同一种/类事物的不同形态

     1 class Animal:
     2     def speak(self):
     3         pass
     4 
     5 class People(Animal):
     6     def speak(self):
     7         print('say hello')
     8 
     9 class Dog(Animal):
    10     def speak(self):
    11         print('汪汪汪')
    12 
    13 class Pig(Animal):
    14     def speak(self):
    15         print('哼哼哼')
    多态

    2、抽象类

    只是用来建立规范的,不能用来实例化的,更无需实现内部的方法

     1 import abc
     2 
     3 class Animal(metaclass=abc.ABCMeta):
     4     @abc.abstractmethod
     5     def speak(self):
     6         pass
     7 
     8     @abc.abstractmethod
     9     def run(self):
    10         pass
    11 
    12 class People(Animal):
    13     def speak(self):
    14         print('say hello')
    15 
    16     def run(self):
    17         pass
    18 
    19 class Dog(Animal):
    20     def speak(self):
    21         print('汪汪汪')
    22 
    23     def run(self):
    24         pass
    25 
    26 class Pig(Animal):
    27     def speak(self):
    28         print('哼哼哼')
    29 
    30     def run(self):
    31         pass
    32 
    33 obj1=People()
    34 obj2=Dog()
    35 obj3=Pig()
    抽象类

    三、封装

    1、什么是封装

    装:往容器/名称空间里存入名字
    封:代表将存放于名称空间中的名字给藏起来,这种隐藏对外不对内

    2、怎么封装

    (1)在类内定义的属性前加__开头(没有__结果)

    (2)__开头的属性实现的隐藏仅仅只是一种语法意义上的变形,并不会真的限制类外部的访问,外部可以调用类内的接口来操作属性

    (3)该变形操作只在类定义阶段检测语法时发生一次,类定义阶段之后新增的__开头的属性并不会变形

     1 class Foo:
     2     __x=111         # _Foo__x    在定义的时候已经将__x改为_Foo__x
     3     __y=222         # _Foo__y    在定义的时候就将__y改成_Foo__y
     4 
     5     def __init__(self,name,age):
     6         self.__name=name     # 函数再定义的时候添加属性,可以被封装
     7         self.__age=age
     8 
     9     def __func(self):     # 在定义的时候已经将__func改为_Foo__func
    10         print('func')
    11 
    12     def get_info(self):
    13         print(self.__name,self.__age,self.__x)  # 内部可以访问封装的属性
    14 
    15 print(self._Foo__name,self._Foo__age,self._Foo__x)
    16 
    17 print(Foo.__x)     # 报错  无法直接访问封装的属性
    18 
    19 print(Foo.__dict__)
    20 
    21 print(Foo._Foo__x)    # 111 封装只是在属性前面加了“_类名”,可以访问封装的属性
    22 
    23 Foo.__z=333
    24 
    25 print(Foo.__z)    # 333 后期添加的属性不会被封装,封装只发生在类定义的阶段

    3、封装数据属性

    (1)将数据属性隐藏起来,类外就无法直接操作属性

    (2)需要类内开辟一个接口来外部的使用可以间接地操作属性,可以在接口内定义任意的控制逻辑,从而严格控制使用对属性的操作

     1 class People:
     2     def __init__(self,name,age):
     3         self.__name=name
     4         self.__age=age
     5 
     6     def tell_info(self):   #接口用来访问封装的数据属性
     7         print('<name:%s age:%s>'  %(self.__name,self.__age))
     8 
     9     def set_info(self,name,age):  # 接口用来修改封装的数据属性的值
    10         if type(name) is not str:
    11             print('名字必须是str类型')
    12             return
    13         if type(age) is not int:
    14             print('年龄必须是int类型')
    15             return
    16         self.__name=name
    17         self.__age=age
    18 
    19 
    20 obj=People('egon',18)
    21 # obj.tell_info()
    22 
    23 # obj.set_info('EGON',19)
    24 # obj.set_info(123,19)
    25 obj.set_info('EGON','18')
    26 obj.tell_info()
    封装的数据属性

    4、封装函数属性

     1 class ATM:
     2     def __card(self):
     3         print('插卡')
     4     def __auth(self):
     5         print('用户认证')
     6     def __input(self):
     7         print('输入取款金额')
     8     def __print_bill(self):
     9         print('打印账单')
    10     def __take_money(self):
    11         print('取款')
    12 
    13     def withdraw(self):
    14         self.__card()
    15         self.__auth()
    16         self.__input()
    17         self.__print_bill()
    18         self.__take_money()
    19 
    20 a=ATM()
    21 a.withdraw()
    封装函数属性

    四、property装饰器

    property装饰器是用来将类内的函数属性伪装成数据属性

     1 class People:
     2     def __init__(self, weight, height):
     3         self.weight = weight
     4         self.height = height
     5 
     6     @property       # property装饰器
     7     def bmi(self):
     8         return self.weight / (self.height ** 2)
     9 
    10 
    11 obj = People(70, 1.75)
    12 
    13 print(obj.bmi)   # bmi被property伪装成数据属性
    property装饰器
     1 class People:
     2     def __init__(self,name):
     3         self.__name=name
     4 
     5     @property
     6     def name(self):
     7         return '<名字:%s>' %self.__name
     8 
     9     @name.setter
    10     def name(self,obj):
    11         if type(obj) is not str:
    12             print('name必须为str类型')
    13             return
    14         self.__name=obj
    15 
    16     @name.deleter
    17     def name(self):
    18         # print('不让删')
    19         del self.__name
    20 
    21 obj=People('egon')
    22 
    23 print(obj.name)        # egon
    24 obj.name='EGON'
    25 #obj.name=123
    26 print(obj.name)    # EGON
    property拓展
  • 相关阅读:
    后缀自动机学习笔记
    [bzoj4516][Sdoi2016]生成魔咒——后缀自动机
    [bzoj1692][Usaco2007 Dec]队列变换——贪心+后缀数组
    BZOJ4811 [Ynoi2017]由乃的OJ
    codeforces796E Exam Cheating
    BZOJ1004 [HNOI2008]Cards
    BZOJ1798 [Ahoi2009]Seq 维护序列seq
    BZOJ4785 [Zjoi2017]树状数组
    UOJ207 共价大爷游长沙
    POJ3768 Katu Puzzle
  • 原文地址:https://www.cnblogs.com/linagcheng/p/9511889.html
Copyright © 2011-2022 走看看