继承
1、在创建类的时候,我们会定义一个类名,并在类名后的括号里加上object
class Teacher(object):
即上方的Teacher类继承于object类。object可以包括所有我们创建的类,object类是所有类的父类,Teacher是object的子类
2、我们用一段代码来更清晰地展示父类和子类
class Person(object):
def __init__(self,name,age):
self.name = name
self.age = age
def show(self):
print(self.name,self.age)
class Student(Person):
pass
stu = Student('zs',20)
stu.show()
在上面的代码中,子类Student继承了父类Person,并在创建了对象stu后,也能直接使用父类的属性和方法。
像这种只继承一个父类的情况,叫做单继承
3、多继承,即子类继承了多个父类,下面用代码说明
class A(object):
def show(self):
print('A')
class B(object):
def show(self):
print('B')
class C(A,B): #子类C继承于两个父类A和B
pass
my_obj = C()
my_obj.show()
A和B中都定义了show方法,在创建了对象my_obj并调用父类的show方法时,输出的结果是A。
之所以只调用了A中的show方法,是因为继承链的关系。
我们可以用print(C.mro())的方法查看C类的继承链,运行后是如下结果
[<class '__main__.C'>, <class '__main__.A'>, <class '__main__.B'>, <class 'object'>]
可以看到,继承链为C-A-B-object。在子类C的对象调用show方法时,会首先在C类中查找是否有定义此方法,如无,则顺着继承链来查看,因此就调用了A类中的show方法。
我们在定义C类时,如将括号内A和B的顺序互换,则C的继承链则会相应发生改变。
重写父类方法
1、子类既能直接使用父类的方法,也能重写父类的方法。当父类的方法满足不了子类的需求时,就可以重写父类方法
2、重写父类方法有几个必须满足的条件:必须存在继承关系、子类重写的方法名必须和父类的相同
3、我们用一段代码来演示
class Person(object):
def eat(self):
print('eat')
class Student(Person):
def __init__(self,name):
self.name = name
def eat(self): #重写父类方法
print('%s eat' % self.name)
stu = Student('zs')
stu.eat()
在子类中我们重写了父类的eat方法,扩展了该方法的功能,当子类创建的对象调用这一方法时,即可实现原有方法不具有的功能。
但是如果是通过父类创建的对象调用eat方法时,输出的结果是Person内定义的功能的输出,并未有任何功能扩展。
4、子类方法中调用父类方法
class Animal(object):
def run(self):
print('animal run')
class Dog(Animal):
def run(self):
print('dog run')
def eat(self):
#方法1,用self调用。如果子类内重写了父类方法,则调用的为子类方法
self.run()
#方法2,用父类名调用,需传入实例self。当继承的父类改变时,需要手动修改父类名
Animal.run(self)
#方法3,用super调用。能够解决上面两个方法的问题
super(Dog,self).run()
print('eat')
d = Dog()
d.eat()
5、这里我们来着重介绍super方法。
在上面的代码中,super括号中的Dog表示从Dog这个类开始,往继承链后的类里找调用的方法。这段代码的继承链为Dog-Animal-object,从Dog方法往后,即先找Animal里是否有run方法,如果没有,再往object类里找
self表示实例对象,可根据这个实例对象找到相应的继承链
6、使用super方法不一定会继承直接父类的方法。如Animal内无run方法而object类里有,那么子类将跨过Animal,去调用object里的方法。如果整个继承链内都没有这个方法,那么执行时将报错
7、用super方法进行多继承中父类方法的调用
class A(object):
def show(self):
print('A')
class B(object):
def show(self):
print('B')
class C(A,B):
def show(self):
super(A,self).show()
#由于类名是作为一个定位,从该类开始往后的继承链查找,故在多继承的情况下,类名不一定为当前类
print('C')
my_obj = C()
my_obj.show()
8、用super方法调用父类的初始化方法
class A(object):
def __init__(self,name):
self.name = name
print('A')
class B(A):
def __init__(self,age):
self.age = age
print('B')
super(B,self).__init__('zs')
#由于A类中的init方法需要传参,在调用时需加注意
b = B(20)
print(b.name)
print(b.age)
9、在使用super方法时可以进行简写,括号内的内容无需填写,这样一来,则默认定位在当前子类