类的“组合”、“封装”
一、组合
1、什么是组合
组合指的是一个对象中包含另一个或者多个对象。
例:一个对象中包含另一个对象
# 用户类 class User: def __init__(self, name, age, sex): self.name = name self.age = age self.sex = sex def run(self): print("user running...") # 日期类 class Date: def __init__(self, year, month, day): self.year = year self.month = month self.day = day def print_birth(self): print(f""" {self.year} {self.month} {self.day} """) # 用户对象 user_obj = User("as", 18, "male") # 日期对象 date_obj = Date(2002, 4, 26) # 用户对象中包含日期对象 user_obj.date_obj = date_obj # 打印日期:可以理解为将日期对象中的名称空间放到用户对象中,用户对象也可以调用日期对象的名称空间(属性和方法) user_obj.date_obj.print_birth()
执行结果:
2002 4 26
2、为什么要使用组合
为了减少代码冗余
3、怎么使用组合
使用例子来详细说明
需求一:打印出老师的姓名、年龄、性别、工资,出生年、月、日;
打印出学生的姓名、年龄、性别、年级,出生年、月、日
# 使用继承
# 使用继承 # 父类:人类 class People: def __init__(self, name, age, sex, year, month, day): self.name = name self.age = age self.sex = sex self.year = year self.month = month self.day = day # 子类:老师类 class Teacher(People): def __init__(self, name, age, sex, sal, year, month, day): # People.__init__(self, name, age, sex) super().__init__(name, age, sex, year, month, day) # 派生 self.sal = sal # 子类:学生类 class Student(People): def __init__(self, name, age, sex, grade, year, month, day): super().__init__(name, age, sex, year, month, day) # 派生 self.grade = grade # 打印老师信息 teacher_obj = Teacher("apple", 17, "female", 99999, 2003, 9, 9) print(teacher_obj.name, teacher_obj.age, teacher_obj.sex, teacher_obj.sal, teacher_obj.year, teacher_obj.month, teacher_obj.day) # 打印学生信息 student_obj = Student("小明", 84, "female", "大五", 1936, 8, 8) print(student_obj.name, student_obj.age, student_obj.sex, student_obj.grade, student_obj.year, student_obj.month, student_obj.day)
执行结果:
apple 17 female 99999 2003 9 9
小明 84 female 大五 1936 8 8
需求二:打印出老师的姓名、年龄、性别、工资;
打印出学生的姓名、年龄、性别、年级,出生年、月、日
# 使用组合
# 使用组合 # 父类:人类 class People: def __init__(self, name, age, sex): self.name = name self.age = age self.sex = sex # 子类:老师类 class Teacher(People): def __init__(self, name, age, sex, sal): super().__init__(name, age, sex) # 派生 self.sal = sal # 子类:学生类 class Student(People): def __init__(self, name, age, sex, grade): super().__init__(name, age, sex) # 派生 self.grade = grade # 生日类 class Date: def __init__(self, year, month, day): self.year = year self.month = month self.day = day def Birthday(self): # 打印出生年、月、日 print(f""" ---出生年月日--- 年:{self.year} 月:{self.month} 日:{self.day} """) # 打印老师信息 teacher_obj = Teacher("apple", 17, "female", 99999) print(teacher_obj.name, teacher_obj.age, teacher_obj.sex, teacher_obj.sal) # 打印学生信息 student_obj = Student("小明", 84, "female", "大五") # 打印学生姓名、年龄、性别、年级 print(student_obj.name, student_obj.age, student_obj.sex, student_obj.grade) obj = Date(1936, 8, 8) # 学生对象中包含一个自定义日期对象 student_date_obj = obj # print(student_date_obj.year, student_date_obj.month, student_date_obj.day) student_date_obj.Birthday()
执行结果:
apple 17 female 99999 小明 84 female 大五 ---出生年月日--- 年:1936 月:8 日:8
4、继承和组合的区别
继承:
继承是类与类的关系,子类继承父类的属性或方法,子类与父类是一种“从属”关系
组合:
组合是对象与对象的关系,一个对象拥有另一个对象中的属性或方法。是一种有什么有什么的关系
5、例:组合例题
需求:
1.有老师和学生类,学生与老师有属性:名字、年龄、性别、课程
2.添加新方法:老师与学生可以添加课程, 打印学习/教授课程。
3.课程类,课程属性:名称、价格、周期
4.使用组合实现
# 人类:父类 class People: def __init__(self, name, age, sex): self.name = name self.age = age self.sex = sex # 添加课程 def add_course(self, course_obj): self.course_list.append(course_obj) # 打印当前对象中课程列表的所有课程信息 def print_all_course_info(self): for course_obj in student_object.course_list: # student_object.course_list --> [python_obj, go_obj] course_obj.print_course_info() # python_obj.print_course_info(), go_obj.print_course_info() # 老师类:子类 class Teacher(People): def __init__(self, name, age, sex): super().__init__(name, age, sex) # 为老师类添加一个课程列表 --> [] self.course_list = [] # 学生类:子类 class Student(People): def __init__(self, name, age, sex): super().__init__(name, age, sex) # 为学生类添加一个课程列表 --> [] self.course_list = [] # 课程类:课程名称、价格、周期 class Cource: def __init__(self, course_name, course_price, course_time): self.course_name = course_name self.course_price = course_price self.course_time = course_time # 定义打印课程方法 def print_course_info(self): print(f""" ---课程信息--- 课程名称:{self.course_name} 课程价格:{self.course_price} 课程周期:{self.course_time} """) # 创建学生对象 student_object = Student("小明", 84, "female") # 创建课程对象 python_obj = Cource("python", 99999, "6个月") go_obj = Cource("go", 88888, "6个月") # 为学生添加课程对象 student_object.add_course(python_obj) student_object.add_course(go_obj) # 打印学生信息 print(student_object.name, student_object.age, student_object.sex) # 为学生打印所有课程信息2 student_object.print_all_course_info()
执行结果:
小明 84 female ---课程信息--- 课程名称:python 课程价格:99999 课程周期:6个月 ---课程信息--- 课程名称:go 课程价格:88888 课程周期:6个月
二、封装(理论)
1、什么是封装
封:比如将一个袋子封起来
装:比如将一堆零食装在袋子里
封装指的是可以将一堆属性和方法,封装到对象中( 对象 --> 相当于一个袋子)
PS:对象就好比一个袋子或者容器,可以存放属性和方法
存不是目的,目的是取,可以通过 "对象.属性/方法" 的方式获取属性或方法
2、为什么要使用封装
方便数据的存取
(可以通过 "对象.属性/方法" 的方式 "存放/获取" 属性或方法,对象拥有 "." 的机制)
3、如何封装
class User: x = 10 def func(self): pass obj = User() # 取 print(obj.x) # 存,存的过程也可以叫做封装 obj.y = 20
# 取 print(obj.y)
执行结果:
10 20