面向对象之继承,组合
一:继承基础
【1】基础概念
(1)继承
(1)定义:是一种定义新类的方式
(2)继承类被称之为子类/派生类 被继承者被称为父类/基类
例如:王思聪继承王健林的财产 那么王思聪就是属于子类 而王健林属于父类
PS:在程序中继承属于 类与类之间的关系
(2)作用:
(1)子类可以继承父类中的某些属性,方法等
(2)子类可以重复使用父类的代码 提高代码的使用量
(3)使用方式:
(1)语法:class +类名(父类名称):
例如:
class Father: pass class Son(Father): pass print(Son.__bases__) # (<class '__main__.Father'>,)
【2】继承扩展:
(1)抽象:
(1)继承描述的是一种什么是什么的关系 在继承之前必须先抽象
(2)抽象是将多个子类具有相同属性和特征抽取出来 形成一个新的类
(3)继承一个已经现存的类 可以修改或者扩展原有功能
案例展示:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
class Father: def __init__(self,name,age): self.name = name self.age = age class Son(Father): def __init__(self, name, age): self.name = name self.age = age fat = Father('爸爸',40) son = Son('儿子',18) print(fat.name) # 爸爸 print(son.name) # 儿子 # PS:可以看见其中有很多重复代码
PS:其中有大量的重复的代码 代码组织架构比较差
解决方法:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
class Person: def __init__(self,name,age): self.name = name self.age = age class Father(Person): print('从上述父类调用') class Son(Person): print('从上述父类调用') fat = Father('爸爸',40) son = Son('儿子',18) print(fat.name) # 爸爸 print(son.name) # 儿子
PS:其通过抽取大量相同的特征 汇总成一个新类 其余类继承这个新类 减少代码的冗余
(2)属性的查找顺序:
(1)首先查找对象本身
(2)查找对象所属的类
(3)查找父类
(4)查找object
例如:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
class Person: # 类被注释 test = '父类' class Father(Person): # 对象被注释 test = '类' pass fat = Father() fat.test = '对象' print(fat.test) ''' 1:对象 2:类 3:父类 '''
(3)派生:
(1)当一个子类出现于父类中不同的内容时候
(2)通常子类都会出现于父类不同的内容 如果完全相同也没什么意义
(3)其主要是为了在继承父类属性和方法之上 扩展自己的功能
例如:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
class Animal: def run(self): print('动物都喜欢跑') class Cat(Animal): # 扩展的新的函数 功能 def eat(self): print('猫喜欢吃鱼') cat = Cat() # 继承父类的行为 cat.run() # 动物都喜欢跑 # 调用新的属性 cat.eat() # 猫喜欢吃鱼 # 添加自己新的属性 cat.color = '黑猫警长' print(cat.color) # 猫喜欢吃鱼
(4)覆盖
(1)也称之为重写
(2)子类出现了与父类一样的东西
(3)当对象在调用的时候会以子类的为准
例如:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
class Animal: def run(self): print('动物都喜欢跑') class Cat(Animal): def run(self): print('动物Cat都喜欢跑') # 扩展的新的函数 功能 def eat(self): print('猫喜欢吃鱼') cat = Cat() # 继承父类的行为 cat.run() # 动物Cat都喜欢跑 直接查找类属性
(4)子类调用父类的方式:
(1)继承:即子类与父类关联比较相近的时候
(2)super:子类与父类关联不是那么相近
(3)指名道姓 父类名.父类方法 子类与父类关联不是那么相近
案例展示:
(1)super:
class Phone: def call(self,name): print('%s使用手机打电话'%name) class Person(Phone): def run(self): super().call('SR') per = Person() per.run() # SR使用手机打电话
(2)指名道姓:
class Phone: def call(self,name): print('%s使用手机打电话'%name) class Person(Phone): def run(self): Phone.call(self,'SR') per = Person() per.run() # SR使用手机打电话
PS:其跟继承没什么关系
练习:如何限制一个元素类型存入空间中
例如:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
# 可以直接调用list作为存储 class My_list(list): # 初始化定义类型 def __init__(self,element_type): self.element = element_type def append(self, object): # 判断初始化类型 是否为自己要加入的 如果是则加入 if type(object) == self.element: super().append(object) else: print('错误的类型') # 调用列表作为存储空间 class My_list(list): # 定义初始化要加入的元素类型 def __init__(self,element_type): self.element_type = element_type # 定义要添加的函数 def append(self, object): # 判断加入的类型 是否为自己想要加入的类型 if type(object) == self.element_type: super().append(object) else: print('类型错误') # 初始化传入类型 m = My_list(int) m.append(1) print(m[0]) # 1 # 报错 其不是整形 m.append('123') print(m[1]) # 类型错误
二:组合
【1】:基础概念
(1)概念
(1)也是一种关系 描述是什么有什么的关系
(2)在python中将一个对象做为令一个对象的属性
(2)组合目的:
(1)也是复用代码
(2)耦合度降低 减少代码之间的影响
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
class Phone: def __init__(self,kind,price,): self.kind = kind self.price = price def call(self): print('正在通话中') class Student: def __init__(self,name,phone): self.name = name self.phone = phone print('%s正在使用手机通话'%self.name) pho = Phone('Apple',9999) stu = Student('SR',pho) stu.phone.call() # 正在通话中
PS:
(1)Student想调用Phone需要将其存入自己的名称空间中
(2)当将其存入自己的名称空间时候 需要保持对象与名称空间一致 于是对象也需要传参
(3)创建对象就是实例化的过程 可以将另外一个类所对应的变量pho以参数的形式上传给类内部的函数中
(4)函数会收到该参数 然后与其交互数据
(3)菱形继承
(1)新式类:
(1)其显示或者隐式属于object的子类
(2)在python3中全部都是新式类
(2)经典类
(1)不属于object的子类
(3)其只在python2中才会出现
(4)菱形查找顺序
(1)经典类:
在python2中多继承情况下 在要查找的属性不存在的时候 会执行深度查找
图解:
(3)新式类:
(1)在python3中如果没有共同的父类 其会执行深度优先
(2)如果其拥有共同的父类其会执行广度优先
PS:
(1)可以通过mro查看查找顺序
(2)在python2中没有这个参数