面向对象:组合、抽象类

组合:适用于“什么有什么”;组合方法: 类1对象.变量 = 类2对象

选课例题:

class LuffyPeople:
    school = "luffycity"

    def __init__(self,name,gender,age):
        self.name = name
        self.gender = gender
        self.age = age


class Teacher(LuffyPeople):

    def __init__(self,name,gender,age,level,salary):
        super().__init__(name,gender,age)

        self.level = level
        self.salary = salary

    def teach(self):
        print("%s is teaching" %self.name)

class Student(LuffyPeople):

    def __init__(self,name,gender,age,class_time):
        super().__init__(name,gender,age)

        self.class_time = class_time

    def learn(self):
        print("%s is learning" %self.name)

class Course:

    def __init__(self,course_name,course_price,course_period):
        self.course_name = course_name
        self.course_price = course_price
        self.course_period = course_period

"""生成两个teacher对象"""
teacher1 = Teacher("alex","male",22,10,3000)
teacher2 = Teacher("egon","male",28,20,5000)

"""生成一个课程对象"""
python = Course("Python",6000,"3mons")

"""
老师对象和课程对象之间: 不是“什么是什么”的关系,所以不能用类的继承;
而是 老师“有”课程 的关系, 所以应该是给老师这个对象添加一个课程的属性
"""
teacher1.course = python   # teacher1.course是一个课程对象
teacher2.course = python   # 通过 .course(变量) 把 teacher1 和 python 这两个变量整合在了一起

print(python)
print(teacher1.course)
print(teacher2.course)
# 打印结果:

  # <__main__.Course object at 0x0000000D52A86B70>
  # <__main__.Course object at 0x0000000D52A86B70>
  # <__main__.Course object at 0x0000000D52A86B70>

"""查看teacher教的课程名"""
print(teacher1.course.course_name)   # teacher1.course.course_name 就相当于 python.course_name  #  给老师这个对象定制了一个课程的属性

# 打印结果:
# Python

"""生成一个学生对象"""
stu1 = Student("neo","male",22,"08:30:00")

为了方便查询课程信息,可以在Course这个类中专门添加一个查询课程信息的功能(函数),如下所示:

class Course:

    def __init__(self,course_name,course_price,course_period):
        self.course_name = course_name
        self.course_price = course_price
        self.course_period = course_period

    """为了方便查询课程信息,可以定义一个课程查询的函数"""
    def tell_info(self):
        print("课程名<%s>  课程价格<%s>  课程周期<%s>" %(self.course_name,self.course_price,self.course_period))

"""查询teacher1的课程信息"""
teacher1.course.tell_info()

# 运行结果:
# 课程名<Python>  课程价格<6000>  课程周期<3mons>

给老师teacher1这个对象定制了一个课程的属性(变量course),然后让这个课程属性(变量course) 指向了另外一个课程对象python,通过这种方式让teacher1 “有了” python;这种“什么有什么”的方式就是“组合”, 把Course类和Teacher类“组合”在了一起。 通过“组合”,能够让好多类组合在一起

如:

"""生成两个课程对象"""
python = Course("Python",6000,"3mons")
linux = Course("Linux",4000,"5mons")

"""生成一个学生对象"""
stu1 = Student("neo","male",22,"08:30:00")

"""给stu1添加python和linux两门课程"""
stu1.course1 = python
stu1.course2 = linux

stu1.course1.tell_info()
stu1.course2.tell_info()

# 运行结果:
# 课程名<Python>  课程价格<6000>  课程周期<3mons>
# 课程名<Linux>  课程价格<4000>  课程周期<5mons>

# 也可以用列表的形式添加课程对象
stu1.course = []
stu1.course.append(python)
stu1.course.append(linux)

print(stu1.course)

# 运行结果:
# [<__main__.Course object at 0x0000002E85B36C88>, <__main__.Course object at 0x0000002E85B36CC0>]
 

 

抽象类:

示例代码如下:

import abc  # 导入 abc 模块

"""抽象类的定义方法"""
class Animal(metaclass=abc.ABCMeta):   #  抽象类的括号里面要传入 metaclass=abc.ABCMeta
    all_type = "animal"  # 抽象类也是类的一种,其内部的功能属性也能够被其子类调用

    @abc.abstractmethod
    def run(self):
        pass

    @abc.abstractmethod
    def eat(self):
        pass
    """
    装饰器:@abc.abstractmethod
    定义函数
    pass (即 不写具体的执行代码)
    """
    """
    这种功能名(函数)在Animal的子类中一定要有,否则子类不能被实例化
    所以通过抽象类的方式,能够统一功能名
    """

class People(Animal):

    def run(self):
        print("people is running")

    def eat(self):
        pass

people = People()  # 因为People这个类中有run和eat这两个功能,所以能够实例化
print(people.all_type)

# 运行结果:
# animal

"""另外,抽象类只能被继承,不能被实例化"""

 

A class that has a metaclass derived from ABCMeta cannot be instantiated unless all of its abstract methods and properties are overridden. The abstract methods can be called using any of the normal ‘super’ call mechanisms.

抽象基类可以有自己的 __init__ 方法。

 

官方参考链接:

https://docs.python.org/3.6/library/abc.html?highlight=abc#module-abc

 

posted @ 2018-03-02 00:23  neozheng  阅读(219)  评论(0编辑  收藏  举报