
(多重继承)[https://www.liaoxuefeng.com/wiki/0014316089557264a6b348958f449949df42a6d3a2e542c000/0014318680104044a55f4a9dbf8452caf71e8dc68b75a18000]
继承是面向对象编程的一个重要的方式,因为通过继承,子类就可以扩展父类的功能
问题
有以下四种动物
- Dog - 狗狗;
- Bat - 蝙蝠;
- Parrot - 鹦鹉;
- Ostrich - 鸵鸟;
如果按照哺乳动物和鸟类归类,我们可以设计出这样的类的层次
但是如果按照“能跑”和“能飞”来归类,我们就应该设计出这样的类的层次:
如果要把上面的两种分类都包含进来,我们就得设计更多的层次
- 哺乳类:能跑的哺乳类,能飞的哺乳类;
- 鸟类:能跑的鸟类,能飞的鸟类
类的层次就复杂了
如果要再增加“宠物类”和“非宠物类”,这么搞下去,类的数量会呈指数增长,很明显这样设计是不行的。
正确的做法是采用多重继承。首先,主要的类层次仍按照哺乳类和鸟类设计:
1 | class Animal(object): #动物类 |
然后我们提前定义好动物具备的行为
1 | class Runnable(object): |
比如让狗继承动物类和跑的行为
1 | class Dog(Mammal, Runnable): #此处继承了 哺乳类 和 跑的行为 |
通过多重继承,一个子类就可以同时获得多个父类的所有功能
MixIn自由继承
在设计类的继承关系时,通常,主线都是单一继承下来的,例如,Ostrich继承自Bird。但是,如果需要“混入”额外的功能,通过多重继承就可以实现,比如,让Ostrich除了继承自Bird外,再同时继承Runnable。这种设计通常称之为MixIn
定制类
str
定义以下函数
1 | class Student(object): |
输出 ><main.Student object at 0x109afb190>
后面序号是内存地址
为了得到对象内部具体数据 我们定义如下
1 | class Student(object): |
输出 Student object (name: Michael)
iter
如果一个类想被用于for … in循环,类似list或tuple那样,就必须实现一个iter()方法,该方法返回一个迭代对象,
然后,Python的for循环就会不断调用该迭代对象的next()方法拿到循环的下一个值,直到遇到StopIteration错误时退出循环
Demo
1 | class Fib(object): |
getitem
Fib实例虽然能作用于for循环,看起来和list有点像,但是,把它当成list来使用还是不行,
比如,取第5个元素:Fib()[5] 就会报错
要表现得像list那样按照下标取出元素,需要实现getitem()方法
1 | class Fib(object): |
list有切片
1 | class Fib(object): |
getattr
正常情况下,当我们调用类的方法或属性时,如果不存在,就会报错。比如定义Student类
1 | class Student(object): |
要想解决这个问题
1.在类中添加score这个属性
2.写一个getattr()方法,动态返回一个属性。修改如下
1 | class Student(object): |
call
创建一个实例的时候自动调用这个方法
1 | class Student(object): |
通过callable()函数可以判断一个对象是否可调用
1 | callable(max) #输出 True 可以调用 |
关于函数定制(官方文档)[https://docs.python.org/3/reference/datamodel.html#special-method-names]