python-類-從入門到精通(二)
0.本文內容--繼承
在上一篇部落格中,講述了python3類的基本使用方法,本篇部落格著重介紹類的繼承特性。
在編寫類的時候,我們不一定都要從空白開始。如果我們正在編寫的類,實際上是另外一個已經存在的類的特殊版本,那麼我們就可以使用類的繼承。B類繼承A類後,B類將自動獲取A類的所有屬性和方法,A類稱為父類,B類稱為子類。子類及繼承了父類的所有屬性和方法,同時還可以定義自己的屬性和方法。
而繼承的實現也很簡單,只要在定義子類的時候,將父類的名稱放到子類名稱後面的括號中即可:
比如,已經定義一個父類為Car(),需要新定義一個子類為ElectricCar()
class ElectricCar(Car):
1.子類__init__()方法
子類繼承父類的所有屬性和方法。既然擁有了使用的權利,那也必須承擔起初始化的責任!如何初始化父類的屬性呢?
這裡需要用到super.__init__()方法。父類也成為超類(superclass),這也是super名稱的由來。
例如,
class Car(): def __init__(self,make,model,year): self.make = make self.model = model self.year = year self.odometer_reading = 0 class ElectricCar(Car): def __init__(self,make,model,year): super().__init__(make,model,year)
在python2.7中,繼承的方式與python3中略有差別,這裡稍作介紹:
class Car(object): def __init__(self,make,model,year): self.make = make self.model = model self.year = year self.odometer_reading = 0 class ElectricCar(Car): def __init__(self,make,model,year): super(ElectriCar,self).__init__(make,model,year)
python2.7中使用繼承時候,需要在super()函式中傳入兩個實參,子類名和物件self。
另外,在父類中需要指定object。
2.定義子類屬性和方法
子類繼承了父類之後,可以新增新的屬性和方法。
class Car():
def __init__(self,make,model,year):
self.make = make
self.model = model
self.year = year
self.odometer_reading = 0
class ElectricCar(Car):
def __init__(self,make,model,year):
super().__init__(make,model,year)
self.battery_size = 70
def describe_battery(self):
print("This car has a " + str(self.battery_size) + '-kwh battery')
父類的屬性和方法一般不能完全滿足子類的需求,否則就不需要新建新的子類了。
繼承只是在一定程度上減少了程式設計的負擔。因此,我們需要在子類中新增我們仍然缺少的方法。
比如新的子類ElectricCar添加了電池容量這一屬性,並使用describe_battery方法,打印出電池容量。
3.重寫父類方法
class ElectricCar(Car):
def fill_gas_tank(self):
print("This car doesn't need a gas tank")
我們的ElectricCar類雖然繼承了Car類,但ElectricCar沒有油箱,把這個方法放在ElectricCar中,這是不合理的。
那麼我們可以通過重寫方法,如果有使用者在ElectricCar中呼叫了fill_gas_tank這個方法,我們給予提示。
4.例項作屬性
類中的屬性既可以是變數,也可以是一個類的例項。
比如,電池這個屬性可能很多類都會用到,那麼我們為什麼不把battery單獨寫成一個類呢?
class Battery():
def __init__(self,battery_size=70):
self.battery_size = battery_size
def describe_battery(self):
print("This car has a "+ str(self.battery_size) + "-kwh battery")
class ElectricCar(Car):
def __init__(self,make,model,year):
super().__init__(make,model,year)
self.battery = Battery()
my_tesla = ElectricCar('tesla','model s',2018)
my_tesla.battery.describe_battery()
這裡需要注意,ElectricCar類與Battery類並不是繼承關係,所以也不會有super().__init__()函式的存在。
當Python執行到ElectricCar類中的self.battery = Battery()時,會自動建立Battery()例項。所以,在程式中我們並沒有建立Battery()類的例項,但是卻可以直接訪問到my_tesla.battery屬性。
在實際應用中,隨著我們專案的推進,我們會不斷地給類新增各種細節。當我們的類過於臃腫的時候,我們可以把比較複雜的部分拆分出來,寫成多個協同工作的小類。