面向对象之组合
一、组合介绍
耦合度越高:程序的可扩展性越低
耦合度越低:程序的可扩展性越高
1、组合的定义
组合指的是一个对象中,包含着另一个或多个对象
2、为什么要用组合
减少代码的冗余
3、如何使用组合
需求:
为老师和学生类添加打印出生年月日功能
利用继承实现
# 1、为老师类和学生类加入 year, month, day
# 2、新增打印出老师和学生的年月日的出生日期
# 通过继承来实现
# 父类
from scipy.constants import year
class People:
def __init__(self, name, age, sex, year, month, day):
self.name = name
self.age = age
self.sex = sex
# 如果使用继承新增出生日期,需要在父类中新增(year, month, day)年月日
self.year = year
self.month = month
self.day = day
# 为其添加第二个功能,打印出生年月日
def print_date(self):
print('''
====== 出生日期 ======
年:%s
月:%s
日:%s
''' % (self.year, self.month, self.day))
# 老师类
class Teacher(People):
# 如果想通过调用父类中的init新增year, month, day,那子类中需要传入year, month, day
def __init__(self, name, age, sex, year, month, day):
# 以及调用父类中的super().__init__的括号中也需要传入年月日
super().__init__(name, age, sex, year, month, day)
# 学生类
class Student(People):
# 学生类中也需要像教师类中的形参,以便传入调用类时,括号里面的年月日
def __init__(self, name, age, sex, year, month, day):
super().__init__(name, age, sex, year, month, day)
# 老师对象
t1 = Teacher('张三', 27, 'male', 1984, 2, 1)
# 学生对象
stu1 = Student('李雷', 20, 'female', 1998, 3, 4)
print(t1.name, t1.age, t1.sex, t1.year, t1.month, t1.day)
# 调用父类中的打印出生日期
t1.print_date()
print(stu1.name, stu1.age, stu1.sex)
stu1.print_date()
利用组合实现
# 父类
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):
super().__init__(name, age, sex)
# 学生类
class Student(People):
def __init__(self, name, age, sex):
super().__init__(name, age, sex)
# 日期类
class Time:
def __init__(self, year, month, day):
self.year = year
self.month = month
self.day = day
def print_time(self):
print('''
==== 出生日期 ====
年:%s
月:%s
日:%s
''' % (
self.year,
self.month,
self.day
))
t1 = Teacher('张三', 39, 'male')
time_obj = Time(1984, 2, 4)
# print(t1.name, t1.age, t1.sex)
# time_obj.print_time()
t1.time_obj = time_obj # 此处相当于为t1对象中添加了time_obj对象的属性和方法
t1.time_obj.print_time()
组合练习
"""
练习需求:
选课系统:
1.有学生、老师类,学生与老师有属性 “名字、年龄、性别、课程”,
2.有方法 老师与学生可以添加课程, 打印学习/教授课程。
# 组合实现
"""
class People:
def __init__(self, name, age, sex):
self.name = name
self.age = age
self.sex = sex
# 添加课程的功能
def add_course(self, course_obj): # self--->stu1
# sut1.course_list = []
self.course_list.append(course_obj) # stu1.course_list.append()
# sut1.course_list.append = [linux_obj, python_obj]
# 打印当前对象中课程列表中的所有课程信息
def print_all_course_info(self): # self ---> stu1
for course_obj in self.course_list: # [python_obj, linux_obj]
# 第一次循环 course_obj ---> python_obj
# python_obj.print_course_info()
# 相当于在调用python_obj对象中的print_course_info方法
# 第二次循环 course_obj ---> linux_obj
# linux_obj.print_course_info()
# 相当于在调用linux_obj对象中的print_course_info方法
course_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 ChoiceCourse:
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('''
课程名字:%s
课程价格:%s
课程时长:%s
''' % (self.course_name,
self.course_price,
self.course_time))
# stu1对象拥有的属性:name,年龄,性别, course_list = [] 方法:add_course(继承自父类), print_all_course_info(继承自父类)
stu1 = Student('韩梅梅', 23, 'female')
# linux_obj对象拥有的属性:course_name, course_price, course_time 方法:print_course_info
linux_obj = ChoiceCourse('linux', 2000, 5)
# python_obj对象拥有的属性:course_name, course_price, course_time 方法:print_course_info
python_obj = ChoiceCourse('python', 2000, 4)
# 学生调用父类中的add_course方法添加课程
stu1.add_course(linux_obj)
stu1.add_course(python_obj)
# 学生调用父类中的打印方法
stu1.print_all_course_info()
4、总结
- 继承
- 继承是类与类的关系,子类继承父类的属性/方法,子类与父类是一种“从属”关系
- 组合
- 组合是对象与对象的关系,一个对象拥有另外一个对象中的属性/方法。