类的“组合”、“封装”

一、组合

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
posted @ 2020-10-26 21:28  chchcharlie、  阅读(227)  评论(0编辑  收藏  举报