组合和多态(继承父类,抽象类,鸭子类型)

[TOC]

组合

1.什么是组合

​ 组合指的是某一个对象拥有一个属性,该属性的值是另外一个类的对象

 class Foo:
        pass
    class Bar:
        pass
    obj=Foo()
    obj.attr=Bar()

    obj.xxx
    obj.attr.yyy

2. 为何要用组合

通过为某一个对象添加属性(属性的值是另外一个类的对象)的方式,可以间接地将两个类关联/整合/组合到一起,从而减少类与类之间代码冗余
 class Foo1:
        pass
    class Foo2:
        pass
    class Foo3:
        pass

    class Bar:
        pass

    obj_from_bar=Bar()

    obj1=Foo1()
    obj2=Foo2()
    obj3=Foo3()

    obj1.attr1=obj_from_bar
    obj2.attr2=obj_from_bar
    obj3.attr3=obj_from_bar

3.组合使用场景

组合与继承都是有效地利用已有类的资源的重要方式。但是二者的概念和使用场景皆不同,
1.继承的方式
通过继承建立了派生类与基类之间的关系,它是一种'是'的关系,比如白马是马,人是动物。
当类之间有很多相同的功能,提取这些共同的功能做成基类,用继承比较好,比如老师是人,学生是人

2.组合的方式
用组合的方式建立了类与组合的类之间的关系,它是一种‘有’的关系,比如教授有生日,教授教python和linux课程,教授有学生s1、s2、s3...
当类之间有显著不同,并且较小的类是较大的类所需要的组件时,用组合比较好

4 .组合使用示例

class People:
    school = 'Oldboy'

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

class Student(People):
    def __init__(self, name, age, sex,score=0):
        People.__init__(self,name,age,sex)
        self.score = score

    def choose_course(self):
        print('%s choosing course' % self.name)

class Teacher(People):
    def __init__(self,name,age,sex,level):
        People.__init__(self,name,age,sex)
        self.level=level

    def score(self,stu,num):
        stu.score=num

class Course:
    def __init__(self,c_name,c_price,c_period):
        self.c_name = c_name
        self.c_price = c_price
        self.c_period = c_period

    def tell_info(self):
        print('<课程名:%s 价钱:%s 周期:%s>' %(self.c_name,self.c_price,self.c_period))

# 创建课程对象
python=Course('python全栈开发',1900,'5mons')
linux=Course('linux架构师',900,'3mons')

stu1=Student('刘二蛋',38,'male')
stu1.course=python
# print(stu1.__dict__)
stu1.course.tell_info()

tea1=Teacher('egon',18,'male',10)
tea1.course=python
# print(tea1.__dict__)
tea1.course.tell_info()

多态

1.多态的定义:

​ 多态指的是同一种事物的多种形态

2.多态的目的:

​ 多态也称之为多态性,在程序中继承就是多态的表现形式。 ​ 多态的目的是为了让多种不同类型的对象,在使用相同的功能(方法)的情况下,都 能做出不同的响应。 ​ 父类:定义一套统一的标准, ​ 子类:遵循父类统一的标准。 ​ 多态的最终目的:统一子类编写规范,为了让使用者更方便调用相同功能的方法。而 多态的精髓就在于统一。

3.如何实现多态

1.继承父类

class Animal:  # 父类定义一套统一的标准,不是为了实现某一具体功能,具体实现功能还是要继承的那些子类,这样使用者只需要学习父类的一套标准就行了。
    def eat(self):
        pass
    def drink(self):
        pass
    def speak(self):
        pass
        # print('我们一起喵喵喵。。。。')

# 猪
class Pig(Animal):
    # 吃
    def eat(self):
        print('猪在吃饭')
        pass
    # 喝
    def drink(self):
        pass
    def speak(self):
         # super().speak()
        print('哼哼哼~~~')
# 猫
class Cat(Animal):
    # 吃
    def eat(self):
        print('猫在吃饭')
       
    # 喝
    def drink(self):
        pass
    def speak(self):
        print('喵喵喵~~')
# 狗
class Dog(Animal):
    # 吃
    def eat(self):
        print('狗在吃饭')
    # 喝
    def drink(self):
        pass
    def speak(self):
        print('汪汪汪~~~')
        
pig = Pig()
cat = Cat()
dog = Dog()

pig.speak()
cat.speak()
dog.speak()

2.抽象类

​ 注意,在Python中不会强制要求子类必须遵循父类的一套标准,所以如果要强制子类遵循父类的一套标准,那么就要使用抽象类。 ​ 1.是什么? ​ 导入 abc(abstract_class)模块 ​ 2.使用的目的? ​ 强制子类必须遵循父类的一套标准 ​ 3.如何使用? ​ import abc

import abc
class Animal(metaclass=abc.ABCMeta):
    # 吃
    @abc.abstractmethod
    def eat(self):
        pass
    # 喝
    @abc.abstractmethod
    def drink(self):
        pass
    # 叫
    @abc.abstractmethod
    def speak(self):
        pass
# Animal() # 父类只是用来建立规范的,不能用来实例化,更无须实现内部的方法。会报错
# 猪
class Pig(Animal):  # 子类在继承父类时,就必须遵循父类制定的规范,即遵守父类内部定义的抽象类方法,否则就报错
    # 吃
    def eat(self):
        print('猪在吃饭')
        pass
    # 喝
    def drink(self):
        pass

    def speak(self):
        print('哼哼哼~~~')

    # 派生
    def run(self):
        pass

pig = Pig()

3.鸭子类型(不推荐强制遵循父类的标准)

​ 鸭子类型:在不知道当前对象是何物的情况下,但你长得像鸭子,那你就是鸭子。 ​ 注意:在Python中,不会强制要求子类必须遵循父类的一套标准,所以出现了鸭子类型。

# python崇尚鸭子类型
class Disk:
    def read(self):
        print('Disk read')

    def write(self):
        print('Disk write')

class Memory:
    def read(self):
        print('Mem read')

    def write(self):
        print('Mem write')

class Cpu:
    def read(self):
        print('Cpu read')

    def write(self):
        print('Cpu write')

obj1=Disk()
obj2=Memory()
obj3=Cpu()

obj1.read()
obj2.read()
obj3.read()

4.实现多态的三种方式的优缺点

​ 继承(继承父类或者抽象类):耦合性太高,扩展性差; ​ 鸭子类型:耦合度低,程序的可扩展性强;

猜你喜欢

转载自www.cnblogs.com/zhangchaocoming/p/11666707.html