假設我想為用戶創建一個包來制作新的汽車類別。最初我有一個簡單的代碼結構:
class Car。
def __init__(self, diesel_engine)。
self._engine = diesel_engine
def _start(self):
pass pass
# 然后用戶就可以做了
class Truck(Car)。
通過。
但現在我想增強功能,在包中同時滿足傳統汽車和電動汽車的需求。問題是基類Car 的建構式現在需要接受diesel_engine或electric_motor;同時,類方法_start將相應地執行不同的事情(因此,例如,它將呼叫_ignite或_close_circuit)。
我是否最好在我的包中加入派生類:
class Conventional(Car)。
def _start(self):
pass: pass
class ElectricVehicle(Car)。
def _start(self):
pass。
或者是否有更好的方法,例如使用裝飾器?從本質上講,我希望最終用戶通過傳遞適當的引數并從一個基類中派生出新的派生類(因為除了_start,其他所有的類方法都是相同的)
uj5u.com熱心網友回復:
抽象的Car應該接受抽象的Engine。
class Car。
def __init__(self, engine: Engine):
self._engine = engine
def start(self)。
self._engine.start()
在現實世界中,發動機可以被視為黑盒子,有一些輸入(氣體/電力)和一些輸出(車軸旋轉、排氣)。發動機盡其所能地隱藏汽車不需要處理的東西。下面的介面提供了一種啟動引擎和控制其速度的方法:
class Engine。
def start(self)。
raise NotImplementedError
def set_speed(self, speed)。
raise NotImplementedError
class DieselEngine(Engine)。
def start(self)。
self._ignite()
def set_speed(self, speed)。
self._set_gas_rate(speed / KILOMETERS_PER_LITER)
但在某些時候,組合并使用資料來做決定會變得更好,而不是繼承層次結構。除非這個層次結構是嚴格不相交的,并且在多個特征之間沒有重疊,否則我將避免繼承,并使用其他方式來模擬 "多型行為"。
例如,如果Car需要將發動機的排氣管道輸送到外部空氣中,那么定義Engine的另一個子類叫做ExhaustEngine就有點愚蠢了。在這一點上,介面(HasExhaust)、PODs、字典等可能更容易操作。
uj5u.com熱心網友回復:
派生類應該設定引擎型別。 通用汽車并不知道這一點。 例如,車輪的數量也是如此。
class Car。
def __init__(self):
self.engine = 'unknown'。
class Truck(Car)。
def __init__(self)。
super().__init__()
self.engine = 'diesel'。
class ElectricCar(Car)。
def __init__(self)。
super().__init__()
self.engine = 'electric'
轉載請註明出處,本文鏈接:https://www.uj5u.com/gongcheng/313404.html
標籤:
