继承
如果两个类具有同名的属性和方法的时候就可以使用继承,例如B类继承A类,那么在B类中就有类A中的属性以及方法。被继承的类叫做父类,继承的而得类叫做子类。继承是面向对象编程的第二个特性。一般来说,父类是一些公有的属性和方法,因此类的继承能够减少代码的冗余,提升代码的可读性,提高开发效率。几乎在所有面向对象的编程中,object类是所有对象的最终继承的类,“祖宗!”。
格式: class 子类名(父类名):
类方法的调用顺序:
子类----->父类----->二级父类------>.......----->object
继承关系是没有限制的,当在子类对象调用一个方法的时候,如果子类的定义中有这个方法的定义就调用子类中的那个方法;如果没有那个方法的定义,就往上看父类有没有这个方法,如果一直到object类都没有找到这个方法的定义就会报错。
重写父类的方法
当子类中定义了和父类的一个同名方法时叫做重写父类的方法。一般来说当父类的方法不能满足子类需求的时候就需要在子类中重写这个方法。
class Dog:
def eat(self):
print("吃狗粮")
def description(self):
print("this is a dog!")
class JunQuan(Dog):
def eat(self):
print("吃肉")
jq = JunQuan()
jq.eat()
jq.description()
结果:
吃肉
this is a dog!
子类中调用父类的方法
子类对象如果调用和父类中同名的方法时默认只会调用自己的方法,在方法中使用super(子类名,self)便可调用到父类的方法。如下代码:
class Dog:
def eat(self):
print("吃狗粮")
class JunQuan(Dog):
def eat(self):
super(JunQuan, self).eat() #得到JuanQuand的父类,然后调用它的eat()方法。
print("吃肉")
jq = JunQuan()
jq.eat()
结果:
吃狗粮
吃肉
重写__init__方法
定义子类对象的时候会调用父类的__init__方法来初始化自身的属性,如果子类中含有父类中没有的属性就需要重写父类的__init__方法。如下代码。此时会发现如果在子类的__init__方法中只定义了子类特有的属性,那么继承自父类的属性反而没有了。因此如果打开最后一行的注释会报错。
class Dog:
def __init__(self):
self.name = "旺旺"
class JunQuan(Dog):
def __init__(self):
self.attri = "搜救"
jq = JunQuan()
print(jq.attri)
#print(jq.name)
结果:
搜救
正确的方式是在子类的__init__方法中使用super(子类名,self).__init__(父类属性的参数),此时子类的__init__方法需要在定义的时候添加一个参数。一般来说super()是写在子类__init__方法的第一行的。
class Dog:
def __init__(self,name):
self.name = name
class JunQuan(Dog):
def __init__(self,name):
super(JunQuan, self).__init__(name)
self.attri = "搜救"
jq = JunQuan("军犬")
print(jq.attri)
print(jq.name)
结果:
搜救
军犬
私有属性和方法的继承问题
类继承只是针对类的公有属性和方法,不能继承类的私有属性和方法。子类如果想要访问父类的私有属性只能通过父类自身的set()和get()方法。
多继承
当子类想同时拥有多个父类的方法时可以 同时继承多个父类,格式: class 子类名(父类1,父类2)
class A:
def funA(self):
print("function from A")
class B:
def funB(self):
print("function from B")
class C(A,B):
pass
c = C()
c.funA()
c.funB()
结果:
function from A
function from B
在多继承中如果两个父类中有同名的方法,那么在子类调用方法的时候默认调用的是第一个父类的方法。
class A:
def funA(self):
print("function from A")
def discription(self):
print("this is A")
class B:
def funB(self):
print("function from B")
def discription(self):
print("this is B")
class C(A,B):
pass
c = C()
c.funA()
c.funB()
c.discription()
结果:
function from A
function from B
this is A
查看继承链:子类名.__mro__()