Python類的繼承
類的繼承可以看成對(duì)類的屬性和方法的重用,能夠大大的減少代碼量,繼承是一種創(chuàng)建新類的方式,在python中,新建的類可以繼承一個(gè)或多個(gè)父類,也就是說在python中支持一個(gè)兒子繼承多個(gè)爹。
通過繼承創(chuàng)建的新類為子類或者派生類,被繼承的類稱為基類、父類或超類
1、子類會(huì)繼承父類所有的功能屬性和方法,并且子類能夠擁有自己的屬性和方法;對(duì)原來的父類不會(huì)產(chǎn)生任何影響。單繼承中只有一個(gè)父類,而多繼承中有多個(gè)父類
2、調(diào)用屬性和方法時(shí),優(yōu)先調(diào)用子類的,子類沒有再調(diào)用父類的,當(dāng)子類的屬性和方法與父類的屬性和方法名稱重復(fù)時(shí),以子類的屬性和方法為準(zhǔn)。
class Person(object):name='Person類name'age='Person類的age'def __init__(self,name,age):self.name=nameself.age=ageprint('這里是Person類的構(gòu)造方法')def eat(self):print('%s 在吃飯(Person類eat方法)'%self.name)def sleep(self):print('%s 在睡覺(Person類sleep方法)'%self.name)class Teacher(Person):name='Teacher類的name'def eat(self):print('%s 在吃飯(Teacher類eat方法)' %self.name)test=Teacher('橙子',11)test.eat()test.sleep()這里是Person類的構(gòu)造方法橙子 在吃飯(Teacher類eat方法)橙子?在睡覺(Person類sleep方法)Process finished with exit code 0
如果子類有構(gòu)造方法,未重寫父類構(gòu)造方法,實(shí)例化子類時(shí),會(huì)調(diào)用子類構(gòu)造方法,實(shí)例屬性會(huì)先找子類的實(shí)例變量,再找子類類變量,最后找繼承類的類變量
class Person(object):name = 'Person類name'age = 'Person類的age'def __init__(self,name,age):self.name=nameself.age=ageprint('這里是Person類的構(gòu)造方法')class Teacher(Person):name='Teacher類的name'def __init__(self,age):self.age=ageprint('這里是Teacher類的構(gòu)造方法')test = Teacher(20)print(test.name,Teacher.name)print(test.age,Teacher.age)這里是Teacher類的構(gòu)造方法Teacher類的name Teacher類的name20?Person類的ageProcess finished with exit code 0
如果子類沒有構(gòu)造方法,未重寫父類構(gòu)造方法,實(shí)例化子類時(shí),會(huì)調(diào)用父類構(gòu)造方法,實(shí)例屬性會(huì)先找子類的實(shí)例變量,再找子類的類變量,最后找父類類變量,類屬性會(huì)先找子類類變量,再找父類類變量
class Person(object):name = 'Person類name'age = 'Person類的age'def __init__(self,name,age):self.name=nameself.age=ageprint('這里是Person類的構(gòu)造方法')class Teacher(Person):name='Teacher類的name'a=111test = Teacher('橙子',30)print(test.name,test.a,Teacher.name)print(test.age,Teacher.age)這里是Person類的構(gòu)造方法橙子 111 Teacher類的name30?Person類的ageProcess finished with exit code 0
3、多重繼承時(shí),有相同名稱的屬性和方法時(shí),會(huì)優(yōu)先找當(dāng)前類下的屬性和方法
class A(object):passclass B(A):passclass C(A):name='C類name'def func(self):print('C類func')class D(C,B):name='D類name'def func(self):print('D類func')test=D()print(test.name)test.func()D類nameD類funcProcess finished with exit code 0
當(dāng)前類下沒有,再找繼承寫在前面的父類的屬性和方法
class A(object):passclass B(A):name='B類name'def func(self):print('B類func')class C(A):name='C類name'def func(self):print('C類func')class D(C,B):passtest=D()print(test.name)test.func()C類nameC類funcProcess finished with exit code 0
前面繼承類沒找到,再去找繼承寫在后面的父類屬性和方法
class A(object):passclass B(A):name='B類name'def func(self):print('B類func')class C(A):passclass D(C,B):passtest=D()print(test.name)test.func()B類nameB類funcProcess finished with exit code 0
父類下都沒找到屬性和方法,再找爺爺類下的屬性和方法
class A(object):name='A類name'def func(self):print('A類func')class B(A):passclass C(A):passclass D(C,B):passtest=D()print(test.name)test.func()A類nameA類funcProcess finished with exit code 0
4、多重繼承時(shí),若子類有構(gòu)造方法,實(shí)例化子類時(shí),會(huì)優(yōu)先自動(dòng)調(diào)用子類構(gòu)造方法;
class A(object):def __init__(self):print('這個(gè)是A類構(gòu)造函數(shù)')passclass B(A):def __init__(self):print('這個(gè)是B類構(gòu)造函數(shù)')passclass C(A):def __init__(self):print('這個(gè)是C類構(gòu)造函數(shù)')passclass D(C,B):def __init__(self):print('這個(gè)是D類構(gòu)造函數(shù)')passtest=D()這個(gè)是D類構(gòu)造函數(shù)Process finished with exit code 0
若子類沒有構(gòu)造方法,會(huì)自動(dòng)調(diào)用寫在前面父類的構(gòu)造方法;再找后面父類的構(gòu)造方法;
class A(object):def __init__(self):print('這個(gè)是A類構(gòu)造函數(shù)')passclass B(A):def __init__(self):print('這個(gè)是B類構(gòu)造函數(shù)')passclass C(A):def __init__(self):print('這個(gè)是C類構(gòu)造函數(shù)')passclass D(B,C):passtest=D()"C:\Program Files\Python35\python.exe" C:/Users/wangli/PycharmProjects/Test/Test/test.py這個(gè)是B類構(gòu)造函數(shù)Process finished with exit code 0
若子類沒有構(gòu)造方法,前面的父類也沒有構(gòu)造方法;會(huì)自動(dòng)調(diào)用后面父類的構(gòu)造方法;
class A(object):def __init__(self):print('這個(gè)是A類構(gòu)造函數(shù)')passclass B(A):passclass C(A):def __init__(self):print('這個(gè)是C類構(gòu)造函數(shù)')passclass D(B,C):passtest=D()"C:\Program Files\Python35\python.exe" C:/Users/wangli/PycharmProjects/Test/Test/test.py這個(gè)是C類構(gòu)造函數(shù)Process finished with exit code 0
若子類和父類都沒有構(gòu)造方法,會(huì)自動(dòng)調(diào)用爺爺類的構(gòu)造方法。
class A(object):def __init__(self):print('這個(gè)是A類構(gòu)造函數(shù)')passclass B(A):passclass C(A):passclass D(B,C):passtest=D()"C:\Program Files\Python35\python.exe" C:/Users/wangli/PycharmProjects/Test/Test/test.py這個(gè)是A類構(gòu)造函數(shù)Process finished with exit code 0
5、調(diào)用父類,若有構(gòu)造函數(shù),在實(shí)例化子類時(shí)就要傳相應(yīng)多的參數(shù),需要多傳參數(shù)時(shí),就需要重構(gòu)父類
6、如果在子類需要父類的構(gòu)造方法就需要顯式地調(diào)用父類的構(gòu)造方法,或者重寫父類的構(gòu)造方法。如果重寫了__init__ 時(shí),實(shí)例化子類,就不會(huì)調(diào)用父類已經(jīng)定義的 __init__,要繼承父類的構(gòu)造方法,可以使用 super 關(guān)鍵字重寫父類構(gòu)造函數(shù)
class Person(object):name='Person類name'age='Person類的age'def __init__(self,name,age):self.name=nameself.age=ageprint(self.name)print('這里是Person類的構(gòu)造方法')class Teacher(Person):def __init__(self,name,age,sex):super(Teacher,self).__init__(name,age)print('這里是Teacher類的構(gòu)造方法')self.sex=sextest=Teacher('橙子',11,'男')print(test.name,test.age,test.sex)橙子這里是Person類的構(gòu)造方法這里是Teacher類的構(gòu)造方法橙子?11?男Process finished with exit code 0
