面向对象进阶
继承
什么是继承?
继承指的是类与类之间的关系,是一种什么“是”什么的关系,继承的功能之一就是用来解决代码重用问题
继承是一种创建新类的方式,在python中,新建的类可以继承一个或多个父类的属性和方法,父类又可以成为基类或超类,新建的类称为派生类或子类,
python中类的继承分为:单继承和多继承
查看继承
class.__bases__#__base__只查看从左到右继承的第一个子类,__bases__则是查看所有继承的父类
继承的查找顺序
先在自己对象里找,然后去类里找,最后去父类里去找
哪一个对象调用,self就是代指的哪一个对象,(父类,子类里的self,都是对象)
经典类与新式类
经典类,广度优先,没有继承object的类,以及它的子类都称之为经典类,没有mro方法,一条道走到黑,
新式类,深度优先,继承object的类,以及它的子类都称之为新式类,有一个内置方法.__mro__( )
python3 都是新式类,一个类没有继承object类,其实是默认继承
python2 新式类,经典类
继承与抽象
抽象即抽取类似或者说比较像的部分。
抽象分成两个层次:
1.将奥巴马和梅西这俩对象比较像的部分抽取成类;
2.将人,猪,狗这三个类比较像的部分抽取成父类。
抽象最主要的作用是划分类别(可以隔离关注点,降低复杂度)
继承:是基于抽象的结果,通过编程语言去实现它,肯定是先经历抽象这个过程,才能通过继承的方式去表达出抽象的结构。
在子类中重用父类的属性
方式一
指名道姓: (不依赖继承)
新方法下执行
def new(): 父类.方法() 父类.__init__() #调用父类的init方法
方式二
super() (依赖继承)
super(自己类名,self).方法() 得到一个父类的对象
super(自己类名,self).__init__()
python3简写为super().方法()
super()从mro列表当前位置往后去找,
组合
组合指的是,在一个类中以另外一个类的对象作为数据属性,称为类的组合
一个类的对象与另一个类的对象组合
与继承的区别在与,组合根据什么有什么的关系,而继承是根据什么是什么的关系,
>>> class Equip: #武器装备类 ... def fire(self): ... print('release Fire skill') ... >>> class Riven: #英雄Riven的类,一个英雄需要有装备,因而需要组合Equip类 ... camp='Noxus' ... def __init__(self,nickname): ... self.nickname=nickname ... self.equip=Equip() #用Equip类产生一个装备,赋值给实例的equip属性 ... >>> r1=Riven('锐雯雯') >>> r1.equip.fire() #可以使用组合的类产生的对象所持有的方法 release Fire skill
抽象类与归一化
规范化子类的方法
抽取多个类的相似部分,集成到一个父类里,让它们都去继承父类
让子类继承的时候必须实现父类规定的方法
抽象类本质上也是一个类,有其他父类的特性
抽象类只能被继承,不能被实例化
import abc
class animal(metaclass=abc.ABCMeta)
@abc.abstractmethod
def eat() 以后继承此类的子类,必须写此方法
多态性:指的是可以在不考虑对象的类型的情况下直接使用对象
鸭子类型:只要你的方法看起来像鸭子,那么我就认为你是鸭子,不用一定要继承父类,只要做得像一点就OK
封装
封装之隐藏
在方法,属性前加下划线进行隐藏
在类定义时,对下划线开头的属性进行变形_class_type
这种变形的特点:
1,在类外部无法直接obj._attrName
2,在类内部是可以直接使用obj._AttrName
3, 子类无法覆盖父类_开头的属性
保护对象的属性:
如果有一个对象,当需要对其进行修改属性时,有2种方法
- 对象名.属性名 = 数据 ---->直接修改
- 对象名.方法名() ---->间接修改
为了更好的保存属性安全,即不能随意修改,一般的处理方式为
- 将属性定义为私有属性
- 添加一个可以调用的方法,供调用
封装数据属性:明确的区分内外,
property的使用
将一些要通过计算才能得到的属性,伪造成数据属性
在定义函数方法的前面加@property,方法加return返回值,使用者可以像使用属性方法那样调用函数方法,即不加括号就能得到数据
定义多个相同方法的删改查操作操作
@property
@property.setter修改
@property.deleter删除
绑定方法与非绑定方法
在类定义的函数分为两大类:
一类:绑定方法(绑定给谁,就应该有谁来调用,谁来调用,就会把调用者当做第一个参数传入)
绑定到对象法:在类内定义的没有被任何装饰器修饰的
绑定到类的方法:在类定义的被classmethod修饰的方法。传入(cls)参数cls=该类
在方法前加入@classmethod
二类:非绑定方法 (没有自动传值这么一说,就是类中定义的一个工具,类和对象都可以使用)
既不与类绑定也不与对象绑定
在方法前加入@staticmethod