组合与封装

一、组合

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__)
复制代码

 

 

 

posted @   treeter  阅读(242)  评论(0编辑  收藏  举报
编辑推荐:
· 聊一聊坑人的 C# MySql.Data SDK
· 使用 .NET Core 实现一个自定义日志记录器
· [杂谈]如何选择:Session 还是 JWT?
· 硬盘空间消失之谜:Linux 服务器存储排查与优化全过程
· JavaScript是按顺序执行的吗?聊聊JavaScript中的变量提升
阅读排行:
· 2000 Star,是时候为我的开源项目更新下功能了
· 好消息,在 Visual Studio 中可以免费使用 GitHub Copilot 了!
· 工作中这样用MQ,很香!
· 使用 .NET Core 实现一个自定义日志记录器
· 没事别想不开去创业!
点击右上角即可分享
微信分享提示