Go-simple(7)基礎教程-邏輯控制
技術標籤:Pythonpythonpython繼承python子類python自學python教程
作者 | 弗拉德
來源 | 弗拉德(公眾號:fulade_me)
繼承
編寫類時,並非總是要從空白開始。如果你要編寫的類是另一個現成類的特殊版本,可使用 繼承。一個類繼承另一個類時,它將自動獲得另一個類的所有屬性和方法;原有的類稱為父類, 而新類稱為子類。子類繼承了其父類的所有屬性和方法,同時還可以定義自己的屬性和方法。
子類的方法__init__()
建立子類的例項時,Python首先需要完成的任務是給父類的所有屬性賦值。為此,子類的方法__init__()
需要繼承父類的方法。
例如,下面來模擬電動汽車。電動汽車是一種特殊的汽車,因此我們可以在前面建立的Car類的基礎上建立新類ElectricCar
下面來建立一個簡單的
ElectricCar
類版本,它具備Car類的所有功能:
class Car():
"""一次模擬汽車的簡單嘗試"""
def __init__(self, make, model, year):
self.make = make
self.model = model
self.year = year
self.odometer_reading = 0
def get_descriptive_name (self):
long_name = str(self.year) + ' ' + self.make + ' ' + self.model
return long_name.title()
def read_odometer(self):
print("This car has " + str(self.odometer_reading) + " miles on it.")
def update_odometer(self, mileage):
if mileage >= self.odometer_reading:
self.odometer_reading = mileage
else:
print("You can't roll back an odometer!")
def increment_odometer(self, miles):
self.odometer_reading += miles
class ElectricCar(Car):
"""電動汽車的獨特之處"""
def __init__(self, make, model, year):
"""初始化父類的屬性"""
super().__init__(make, model, year)
my_tesla = ElectricCar('tesla', 'model s', 2016)
print(my_tesla.get_descriptive_name())
首先是Car類的程式碼。建立子類時,父類必須包含在當前檔案中,且位於子類前面。接著我們定義了子類ElectricCar
。定義子類時,必須在括號內指定父類的名稱。方法__init__()
接受建立Car例項所需的資訊。
ElectricCar
內部的super()
是一個特殊函式,幫助Python將父類和子類關聯起來。這行程式碼讓Python呼叫ElectricCar
的父類的方法__init__()
,讓ElectricCar
例項包含父類的所有屬性。父類也稱為超類(superclass
),名稱super因此而得名。
接下來我們測試一下繼承的作用,我們嘗試建立一輛電動汽車,但提供的資訊與建立普通汽車時相同。我們建立ElectricCar
類的一個例項,並將其儲存在變數my_tesla
中。這行程式碼呼叫ElectricCar
類中定義的方法__init__()
,後者讓Python呼叫父類Car中定義的方法 __init__()
。我們提供了實參’tesla’、'model s’和2016。
除方法__init__()
外,電動汽車沒有其他特有的屬性和方法。當前,我們只想確認電動汽車具備普通汽車的行為,輸出結果如下:
2016 Tesla Model S
ElectricCar例項的行為與Car例項一樣,現在可以開始定義電動汽車特有的屬性和方法了。
給子類定義屬性和方法
讓一個類繼承另一個類後,可新增區分子類和父類所需的新屬性和方法。
下面來新增一個電動汽車特有的屬性(電瓶),以及一個描述該屬性的方法。我們將儲存電瓶容量,並編寫一個列印電瓶描述的方法:
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.")
my_tesla = ElectricCar('tesla', 'model s', 2016)
print(my_tesla.get_descriptive_name())
my_tesla.describe_battery()
我們添加了新屬性self.battery_size
,並設定其初始值。根據ElectricCar
類建立的所有例項都將包含這個屬性,但所有Car例項都不包含它。我們還添加了一個名為describe_battery()
的方法,它列印有關電瓶的資訊。我們呼叫這個方法時,將看到一條電動汽車特有的描述:
2016 Tesla Model S
This car has a 70-kWh battery.
對於ElectricCar類的特殊化程度沒有任何限制。模擬電動汽車時,你可以根據所需的準確程度新增任意數量的屬性和方法。如果一個屬性或方法是任何汽車都有的,而不是電動汽車特有的,就應將其加入到Car類而不是ElectricCar類中。這樣,使用Car類的人將獲得相應的功能,而 ElectricCar類只包含處理電動汽車特有屬性和行為的程式碼。
重寫父類的方法
對於父類的方法,只要它不符合子類模擬的實物的行為,都可對其進行重寫。為此,可在子類中定義一個這樣的方法,即它與要重寫的父類方法同名。這樣,Python將不會考慮這個父類方法,而只關注你在子類中定義的相應方法。
假設Car
類有一個名為fill_gas_tank()
的方法,它對全電動汽車來說毫無意義,因此你可能想重寫它。下面演示了一種重寫方式:
def ElectricCar(Car):
def fill_gas_tank():
"""電動汽車沒有油箱"""
print("This car doesn't need a gas tank!")
現在,如果有人對電動汽車呼叫方法fill_gas_tank()
,Python將忽略Car類中的方法fill_gas_tank()
,轉而執行上述程式碼。使用繼承時,可讓子類保留從父類那裡繼承的有用的程式碼,用重寫來覆蓋不需要的程式碼。
本篇文章沒有作業,下一篇我們講解函式的高階用法