class Father():
name = "老方"
sex = "男"
def __init__(sef):
print("Father构造函数运行")
def speak_english(self):
print("father说英语")
def __juehuo(self):
print("father的绝活")
class Child(Father): #继承Fathe这个类的名字
pass
#如果Chind中不写任何方法,可以调用方法吗?
c = Child() #因为Child里没有写构造函数,将运行Father的构造函数,如果Child中自己有构造函数,将运行自己的构造函数。
c.speakenglish() #可以被调用,这个方法是从父亲那里继承过来的,但是__juehuo()这个方法不可以被调用,因为它是father的私有方法。
class Child(Father):
def __init__(self):
print("Child构造函数运行")
def speakenglish(self):
print("Child说英语")
c = Child()
c.speakenglish() #当Child中的方法和父类中的方法同名时,将调用自己的方法,自己没有同名的方法的才会到父类中调用。
# 以上例子是一个单继承,下面举一个多继承的例子
##**********************************************
class Mother():
name = "韩梅梅"
sex = "女"
def __init__(self):
print("Mother构造函数运行")
def speakchinese(self):
print("Mother说中文")
class Child(Father, Mother):
pass
c = Child()
c.speakenglish()
c.speakchinese()
print(child.__bases__) # __bases__它是查看所有的继承的父类,继承顺序是从左到右,这个顺序就是在定义子类时填写父类的顺序。
因此,在Child中子类不写构造函数时,你会发现它运行的是Father的构造函数。
也就是说,子类在找方法时,先找自己,自己没有再找最左边的父类,没有再按顺序往右逐个寻找。
思考一个问题,那么为什么要用继承?
最简单的出发点可能是减少代码的重复,但是出发点很多,其中通过父类来定义某种规则,是其中一种。
就像电脑的组装一样,电脑生产商只给电脑留USB接口,但是USB可以接很多不同种类设备,设备提供商必须按照电脑定义的USB规则
来提供USB设备,否则不可以在电脑是上使用。下面通过一个例子来认识下父类对规则的定义
from abc import ABCMeta, abstractmethod
class Tester(metaclass=ABCMeta):
def test(self):
pass
class FunctionTester(Tester):
pass
f = FunctionTester()
f.test()
上面这个时候,子类是可以调用父类中test方法的。
如果把父类修改成如下:
class Tester(metaclass=ABCMeta): #metaclass是元类,以后在别的文章上专门介绍
@abstractmethod
def test(self):
pass
这个时候,编译时就会报错,提示子类中没有定义test方法。@abstractmethod的作用就是在父类中定义了一种规则,要求子类中必须同样需要定义这种方法。
因此子类中必须增加
def test(self):
pass
以上就是父类对子类的一种规则定义和约束。
继承的深度优先和广度优先概念
class A():
def test(self):
print("继承A")
class B(A):
def test(self):
print("继承B")
class C(A):
def test(self):
print(“C”)
class D(B):
pass
class E(C):
def test(self):
print(“E”)
class F(D,E):
pass
f = F()
f.test()
此时test方法继承谁呢?
可以通过print(F.__mro__)来解密下
继承顺序为D->B->E->C->A,通过一张图来说明
总结:先深度优先,在到达公共父类时,将换广度(即左右顺序父类)来查找,如果最后所有的广度都没有找到继承的方法,才会去公共父类里查找继承的方法。
原文:https://www.cnblogs.com/laofang/p/12076463.html