目录
组合
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.实现多态的三种方式的优缺点
继承(继承父类或者抽象类):耦合性太高,扩展性差;
鸭子类型:耦合度低,程序的可扩展性强;