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