python學習之-繼承與派生
什麼是繼承
繼承是一種新建類的方式,新建的類稱之為子類/派生類,被繼承的類稱之為父類\基類\超類
繼承描述的是一種遺傳的關係,父類的屬性可以被子類訪問到
為何要繼承
解決類與類之間程式碼冗餘的問題
如何用繼承
在python中繼承的特點:
1. 在python中一個子類可以同時繼承多個父類
2. 在python3如果一個類沒有指明繼承的類,預設繼承object,在python2如果一個類沒有指明繼承的類,不會預設繼承object
Python中的類分成兩種
新式類
但凡繼承了object類的子類,以及該子類的子子類都是新式類
經典類
沒有繼承object類的子類,以及該子類的子子類都是經典類
在python3全都是新式類
在python2中才去分經典類與新式類
class Parent1(object): #Python2中類定義傳入引數object就是新式類
pass
繼承例項
class Parent1(object): #這是父類 ,傳入一個object引數,是為了相容Python2,所以如果要向下相容這裡必須寫
pass
class Parent2(object): #這是父類
pass
class Sub1(Parent1): #這是子類單繼承
pass
class Sub2(Parent1,Parent2): #這是子類,而且是多繼承
pass
PS:如何繼承,就是子類把父類當做引數傳入下面的程式碼中
檢視繼承的方法__bases__
print(Sub1.__bases__)
print(Sub2.__bases__)
檢視父類的繼承
print(Parent1.__bases__)
print(Parent2.__bases__)
PS:可以看到是一個類object,在python3如果一個類沒有指明繼承的類,預設繼承object
繼承例項
class Animal: def eat(self): print("%s 吃 " %self.name) def drink(self): print ("%s 喝 " %self.name) def shit(self): print ("%s 拉 " %self.name) def pee(self): print ("%s 撒 " %self.name) class Cat(Animal): def __init__(self, name): self.name = name self.breed = '貓' def cry(self): print('喵喵叫') class Dog(Animal): def __init__(self, name): self.name = name self.breed='狗' def cry(self): print('汪汪叫') # ######### 執行 ######### c1 = Cat('小白家的小黑貓') c1.eat() c2 = Cat('小黑的小白貓') c2.drink() d1 = Dog('胖子家的小瘦狗') d1.eat()
繼承的背景下屬性查詢
在單繼承背景下新式類經典類屬性查詢都一樣: 物件->物件的類->父類->父父類...
class Foo:
# xxx=222
pass
class Bar(Foo):
# xxx=111
pass
obj=Bar()
# obj.xxx=0
print(obj.xxx)
PS:查詢xxx屬性,如果物件裡面沒有,則去類裡面找,類裡面沒有則去父類找,父類沒有則去object裡面找然後會報錯,這一點新式類和經典類都一樣
練習:self.f1是查找了父類的還是自身的
class Foo:
def f1(self):
print('Foo.f1')
def f2(self):
print('Foo.f2')
self.f1() # obj.f1()
class Bar(Foo):
def f1(self):
print('Bar.f1')
obj = Bar()
obj.f2()
首先建立了一個物件呼叫的是bar類,然後查詢f2屬性,bar類下沒有,則去父類中查詢,父類中有f2這個屬性,則查詢到,然後f2屬性下又呼叫了自身下的屬性f1,所以最終查詢的是自己的f1屬性,而不是父類下的,因為一開始查詢f2的時候自身沒有,因為繼承了父類的屬性,所以又去父類中查詢,父類中的f2下呼叫的是自身,因為一開始查詢的時候就將自身傳入了父類中去查詢,所以最後呼叫的是自己
在子類派生的新方法中重用父類的功能
方式一
class OldboyPeople:
school = 'Oldboy'
def __init__(self,name,age,gender):
self.name=name
self.age=age
self.gender=gender
class OldboyStudent(OldboyPeople):
def choose_course(self):
print('%s is choosing course' %self.name)
class OldboyTeacher(OldboyPeople):
def __init__(self, name, age, gender,level): #如果父類引數滿足不了,則可以重新派生定義一個新的,這裡就是定義一個新的派生,用內建方法__init__
OldboyPeople.__init__(self,name, age, gender) #這就是子類派生的新方法中重用父類功能,類呼叫物件就是呼叫函式,所以少一個引數都不行,這裡就是重用父類的功能
self.level=level #這一段是需要自己增加的程式碼
def score(self,stu,num):
stu.score=num
print('老師[%s]為學生[%s]打了分[%s] ' %(self.name,stu.name,num))
stu1=OldboyStudent('王大炮',18,'male') #初始化學生的資訊
print(stu1.__dict__) #檢視有沒有初始化成功
tea1=OldboyTeacher('Egon',18,'male',10) #初始化老師的資訊,如果有重用父類功能,這裡也要傳入相應的引數
print(tea1.__dict__) #檢視有沒有初始化成功