zoukankan      html  css  js  c++  java
  • 组合与封装

    一、组合

    1.什么是组合

    组合指的是一个对象中,包含另一个或多个对象。

    2、组合作用

    减少代码的冗余

    ps:耦合度:

      耦合度越高,程序的可扩展性越低;相反,耦合度越低,程序的可扩展性就越高

    这里有个程序通过和继承的比较,可以显示这个作用。

     1 # 继承
     2 # 父类
     3 class People:
     4     def __init__(self, name, age, sex, year, month, day):
     5         self.name = name
     6         self.age = age
     7         self.sex = sex
     8         self.year = year
     9         self.month = month
    10         self.day = day
    11 
    12     def print_birth(self):
    13         print(f"""
    14         ===== 出生年月日 =====
    15             年: {self.year}
    16             月: {self.month}
    17             日: {self.day}
    18         """)
    19 
    20 
    21 class Teacher(People):
    22     pass
    23 
    24 class Student(People):
    25     pass
    26 
    27 t1 = Teacher('张三', 24, '', 1995, 1, 1)
    28 s1 = Student('李四', 28, '', 1991, 4, 1)
    29 
    30 print(t1.year, t1.month, t1.day)
    31 t1.print_birth()
    32 print(s1.year, s1.month, s1.day)
    33 s1.print_birth()
     1 # 组合实现
     2 class People:
     3     def __init__(self, name, age, sex):
     4         self.name = name
     5         self.age = age
     6         self.sex = sex
     7 
     8 class Teacher(People):
     9     pass
    10 
    11 class Student(People):
    12     pass
    13 
    14 class Date:
    15     def __init__(self, year, month, day):
    16         self.year = year
    17         self.month = month
    18         self.day = day
    19 
    20     def print_birth(self):
    21         print(f"""
    22         ===== 出生年月日 =====
    23             年: {self.year}
    24             月: {self.month}
    25             日: {self.day}
    26         """)
    27 
    28 t1 = Teacher('张三', 24, '')
    29 t_date = Date(1995, 1, 1)
    30 t1.t_date = t_date
    31 
    32 s1 = Student('李四', 28, '')
    33 s1_date = Date(1991, 4, 1)
    34 s1.s1_date = s1_date
    35 
    36 print(t1.t_date.year, t1.t_date.month, t1.t_date.day)
    37 t1.t_date.print_birth()

    组合练习:

    练习需求:
    选课系统:
    1.有学生、老师类,学生与老师有属性 “名字、年龄、性别、课程”,
    2.有方法 老师与学生可以添加课程, 打印学习/教授课程。

     1 class People:
     2     def __init__(self, name, age, sex):
     3         self.name = name
     4         self.age = age
     5         self.sex = sex
     6 
     7     # 打印出生日期方法
     8     def print_birth(self):
     9         print(f"""
    10         年:  {self.birthday.year}
    11         月:  {self.birthday.month}
    12         日:  {self.birthday.day}
    13         """)
    14 
    15     # 添加课程
    16     def add_course(self, course_obj):
    17         self.course_list.append(course_obj)
    18 
    19     # 打印课程信息
    20     def print_all_course(self):
    21         # 从当前对象中课程列表中取出所有的课程对象
    22         for course_obj in self.course_list:
    23             course_obj.print_course()
    24 
    25 class Teacher(People):
    26     def __init__(self, name, age, sex):
    27         super().__init__(name, age, sex)
    28         self.course_list = []
    29 
    30 class Student(People):
    31     def __init__(self, name, age, sex):
    32         super().__init__(name, age, sex)
    33         self.course_list = []
    34 
    35 class Date:
    36     def __init__(self, year, month, day):
    37         self.year = year
    38         self.month = month
    39         self.day = day
    40 
    41     # def print_birth(self):
    42     #     print(f"""
    43     #     ===== 出生年月日 =====
    44     #         年: {self.year}
    45     #         月: {self.month}
    46     #         日: {self.day}
    47     #     """)
    48 
    49 class Course:
    50     def __init__(self, name, price, period):
    51         self.name = name
    52         self.price = price
    53         self.period = period
    54 
    55     # 定义打印课程方法,只打印一个课程信息
    56     def print_course(self):
    57         print(f"""
    58         -------- 课程信息 --------
    59         课程名称:   {self.name}
    60         课程价格:   {self.price}
    61         课程周期:   {self.period}
    62         """)
    63 
    64 
    65 # 创建学生对象
    66 stu1 = Student("张三", 23, "")
    67 date_obj = Date('1996', '2', '14')
    68 stu1.birthday = date_obj
    69 stu1.print_birth()
    70 
    71 
    72 # 创建课程对象
    73 python = Course('python', 12312, 6)
    74 linux = Course('linux', 13421, 4)
    75 
    76 # 当前学生添加了课程对象
    77 # 添加python课程
    78 stu1.add_course(python)
    79 # 添加linux课程
    80 stu1.add_course(linux)
    81 
    82 stu1.print_all_course()

    小结:

    - 继承:
      继承是类与类的关系,子类继承父类的属性/方法,子类与父类是一种 “什么是什么” 关系。

    - 组合:
      组合是对象与对象的关系,一个对象拥有另一个对象中的属性/方法,是一种“什么有什么”的关系。

    二、封装

    1.什么是封装

    封装指的是可以将一堆属性和方法,封装到对象中

    PS: 对象就好比一个 “袋子/容器”,可以存放一对属性和方法。
    PS: 存不是目的,目的是为了取,可以通过 “对象.” 的方式获取属性或方法。

    2.封装作用

    可以通过 “对象.” 的方式 “存放/获取” 属性或方法。
    对象拥有 "." 的机制。
    方便数据的存取。

    三、限制访问机制

    1.什么是限制访问机制

    凡是在类内部定义的属性或方法,以__开头的属性或方法名,都会被限制,外部不能 “直接访问” 该属性原型,看着像将该属性或方法隐藏起来了

    2.限制访问的作用

    将一些隐私的数据,隐藏起来,不让外部轻易获取

    - 接口:
      可以将一对数据封装成一个接口, 可以让用户调用接口,
      并且通过相应的逻辑,最后再将数据返回给用户。

    凡是在类内部定义__开头的属性或方法,都会变形为 _类名__属性/方法

     1 # demo1
     2 class User:
     3     # __开头的属性
     4     __name = '张三'   # __name变形为 ---》 _类名__name ---》 _User__name
     5     # __开头的方法
     6     def __func(self):
     7         print('func')
     8 
     9 print(User.__dict__)
    10 user_obj = User()
    11 print(user_obj._User__name)
    12 user_obj._User__func()
     1 # demo2
     2 class User:
     3     # __开头的属性
     4     __name = '李四'  # __name变形为 ---》 _类名__name
     5     __age = 32
     6     __sex = ''
     7     __ID = '412533198712245745'
     8     __bal = 1500
     9     # def __init__(self, name, age, sex):
    10     #     self.__name = name
    11     #     self.__age = age
    12     #     self.__sex = sex
    13     # 校验接口,获取用户信息
    14     def parse_user(self, username, password):
    15         if username == 'tank_jam' and password == '123':
    16             print(f'''
    17             通过验证,获取用户信息。
    18             用户名: {self.__name}
    19             用户年龄: {self.__age}
    20             用户性别: {self.__sex}
    21             身份ID: {self.__ID}
    22             用户资产: {self.__bal}
    23             ''')
    24         else:
    25             print('校验失败, 无法查询用户信息!')
    26 
    27     # __开头的方法
    28     def __run(self):
    29         print('tank is running...')
    30 
    31 obj = User()
    32 obj.parse_user('tank_jam', '123')
     1 # demo3:
     2 class ATM:
     3     # 取钱功能:
     4     # 1.插入磁卡
     5     def __insert_card(self):
     6         print('开始插卡...')
     7         pass
     8 
     9     # 2.输入密码
    10     def __input_pwd(self):
    11         print('输入密码...')
    12         pass
    13 
    14     # 3.输入取款金额
    15     def __input_bal(self):
    16         print('输入取款金额...')
    17         pass
    18 
    19     # 4.吐钱
    20     def __output_money(self):
    21         print('开始吐钱...')
    22         pass
    23 
    24     # 5.打印流水账单
    25     def __print_flow(self):
    26         print('打印流水账单...')
    27         pass
    28 
    29     # 取款顺序规范接口:
    30     def withdraw(self):
    31         # 1.插入磁卡
    32         self.__insert_card()
    33 
    34         # 2.输入密码
    35         self.__input_pwd()
    36 
    37         # 3.输入取款金额
    38         self.__input_bal()
    39 
    40         # 4.吐钱
    41         self.__output_money()
    42 
    43         # 5.打印流水账单
    44         self.__print_flow()
    45 
    46 
    47 amt_obj = ATM()
    48 amt_obj.withdraw()

    四、property

    1.什么是property

    是一个python内置的装饰器,可以装饰在"类内部的方法"上。
    可以将该方法调用方式由 ----> 对象.方法() ---> 对象.方法

    2.property作用

    去掉()后,让名词的方法,调用时更为合理。

     1 # 需求: 计算人体 bmi 指数
     2 # 体重 / 身高的平方
     3 # value = weight / (height * height)
     4 class Bmi:
     5     def __init__(self, name, weight, height):
     6         self._name = name
     7         self.weight = weight
     8         self.height = height
     9     @property
    10     def bmi(self):
    11         return self.weight / (self.height ** 2)
    12 
    13     @property
    14     def name(self):
    15         return self._name
    16     # 了解: 设置被property装饰后的方法
    17     # 注意: 需要修改的方法名字要与被property装饰器后的方法一样
    18     @name.setter
    19     def name(self, value):
    20         self._name = value
    21     @name.deleter
    22     def name(self):
    23         del self._name
    24 
    25 bmi_obj = Bmi('张三', 60, 1.8)
    26 # print(bmi_obj.bmi())
    27 print(bmi_obj.bmi)
    28 
    29 print(bmi_obj.name)
    30 bmi_obj.name = '李四'
    31 print(bmi_obj.name)
    32 
    33 print(bmi_obj.__dict__)
    34 del bmi_obj.name
    35 print(bmi_obj.__dict__)
  • 相关阅读:
    Unix环境编程之文件IO
    navicat 导出查询结果
    Java 原子类 java.util.concurrent.atomic
    AtomicBoolean介绍
    ExecutorService常用方法和newFixedThreadPool创建固定大小的线程池
    ExecutorService与Executors例子的简单剖析
    tomcat6版本虚拟目录详细配置
    生产者与消费者模型案例
    如何设计一个LRU Cache
    在MVC模式下通过Jqgrid表格操作MongoDB数据
  • 原文地址:https://www.cnblogs.com/hexianshen/p/11943026.html
Copyright © 2011-2022 走看看