组合
一、什么是组合
- 组合就是一个类的对象具备某一个属性,该属性的值是指向另外一个类的对象(对象的某个属性是另一个类的对象)
"""
1. 什么是组合
对象的某个属性是另一个类的对象
"""
# 组合的概念
class Foo:
def __init__(self, bar):
self.bar = bar
class Bar:
pass
# f = Foo()
bar = Bar()
f1 = Foo(Bar())
f2 = Foo(bar)
二、为什么用组合
- 组合是用来解决类与类之间代码冗余的问题(减少代码的冗余)
- 首先我们先写一个简单版的选课系统
class Person:
school = 'hnnu'
class Teacher(Person):
def __init__(self, name, age, level, course_name, course_price, course_period):
self.name = name
self.age = age
self.level = level
self.course_name = course_name
self.course_price = course_price
self.course_period = course_period
class Student(Person):
def __init__(self, name, age, level, course_name, course_price, course_period):
self.name = name
self.age = age
self.level = level
self.course_name = course_name
self.course_price = course_price
self.course_period = course_period
# 编写复杂繁琐
teacher = Teacher("张老师", 19, '教授', 'python', '190', '一周')
student = Student("小明", 15, '学生', 'python', '190', '一周')
简单化
通过组合解决代码冗余
class Person:
school = 'hnnu'
class Teacher(Person):
def __init__(self, name, age, level, course):
self.name = name
self.age = age
self.level = level
# 保存对象
self.course = course
class Student(Person):
def __init__(self, name, age, course):
self.name = name
self.age = age
self.course = course
class Course():
def __init__(self, course_name, course_price, course_period):
self.name = course_name
self.price = course_price
self.period = course_period
course = Course('python', 1000, 8)
stu = Student('laowang', 18, course)
tea = Teacher('randy', 19, "教授", course)
# 查看老师教授的课程名
print(f'{tea.name}传授的课程{tea.course.name}')
如上设计了一个选课系统,但是这个选课系统在未来一定是要修改、扩展的,因此我们需要修改上述的代码
三、如何使用
- 需求:假如我们需要给学生增添课程属性,但是又不是所有的老男孩学生一进学校就有课程属性,课程属性是学生来后选出来的,也就是说课程需要后期学生们添加进去的
- 实现思路:如果我们直接在学生中添加课程属性,那么学生刚被定义就需要添加课程属性,这就不符合我们的要求,因此我们可以使用组合能让学生未来添加课程属性
# 通过组合解决代码冗余
class Person:
school = 'hnnu'
class Teacher(Person):
def __init__(self, name, age, level, course):
self.name = name
self.age = age
self.level = level
# 保存对象
self.course = course
class Student(Person):
def __init__(self, name, age):
self.name = name
self.age = age
# course是课程对象,表示选的课程
self.course_list = []
def choose_course(self, course):
# 把课程对象添加到学生选课列表中
self.course_list.append(course)
def tell_all_course(self):
# 查看学生选择的学生
for course in self.course_list:
print(f'{self.name}学生选择的课程{course.name}')
class Course():
def __init__(self, course_name, course_price, course_period):
self.name = course_name
self.price = course_price
self.period = course_period
course = Course('python', 100, 8)
stu1 = Student('laowang', 18)
stu1.choose_course(course)
stu2 = Student("王二丫", 19)
stu2.choose_course(course)
stu2.choose_course(Course('linux', 199, 10))
# 方式一
stu1.tell_all_course()
# 方式二
def print_course(student):
for course in student.course_list:
print(course.name)
print_course(stu1)
四、总结
-
组合指的是,在一个类中以另外一个类的对象作为数据属性,称为类的组合
-
组合与继承都是有效地利用已有类的资源的重要方式。但是二者的概念和使用场景皆不同,
-
继承的方式
通过继承建立了派生类与基类之间的关系,它是一种'是'的关系,比如白马是马,人是动物。
当类之间有很多相同的功能,提取这些共同的功能做成基类,用继承比较好,比如老师是人,学生是人
-
组合的方式
用组合的方式建立了类与组合的类之间的关系,它是一种‘有’的关系,比如教授有生日,教授教python和linux课程,教授有学生s1、s2、s3...
-