2011-08-16 152 views
2

我有一個基類的實例,然後我想使它成爲此基類的子類的實例。也許我以一種錯誤的方式解決問題,在OOP中有一些重要的東西我不明白。代碼只是爲了說明,並且可以提出一種非常不同的方法。任何幫助讚賞。繼承:將基類實例轉換爲子類實例

class Car(object): 
    def __init__(self, color): 
     self.color = color 

    def drive(self): 
     print "Driving at 50 mph" 

class FastCar(Car): 
    def __init__(self, color, max_speed=100): 
     Car.__init__(self, color) 
     self.max_speed = max_speed 

    def drive_fast(self): 
     print "Driving at %s mph" %self.max_speed 

one_car = Car('blue') 

# After the instanciation, I discovered that one_car is not just a classic car 
# but also a fast one which can drive at 120 mph. 
# So I want to make one_car a FastCar instance. 

我看到一個非常類似的問題,但沒有答案的適合我的問題:

  • 我不想讓FastCar圍繞汽車的包裝,其知道如何開快車:我真的希望FastCar擴展Car;

  • 我真的不希望使用FastCar的__new__方法做出的論點一些測試,並決定是否__new__必須返回車的新實例或者我給它的實例(例如:def __new__(cls, color, max_speed=100, baseclassinstance=None))。

+0

爲什麼你不這樣做:one_car = FastCar(one_car.color,120)?這不是真正的繼承或什麼,但應該工作。 – Bogdan

+3

您的OOP設計看起來有點不合適。我會想象FastCar也會實現drive(),但是會以更高的速度執行(你已經實現了drive_fast)。用你現在擁有的東西,調用者必須知道類型以知道調用哪個方法(壞),而不是調用相同的方法,並讓各種類型適當地實現該方法(良好)。您也可以通過在FastCar類的末尾添加'drive = drive_fast'來完成此操作。 – PaulMcG

+0

好的。一個更好的例子:'FastCar'沒有'drive_fast'方法,但是'overtake'方法不存在'Car'。 – Andy

回答

0

您可以借用「複製構造函數」的C++概念來做這樣的事情。

允許Car的構造函數採用Car實例,並複製其所有屬性。 FastCar應該接受Car實例或FastCar實例。

那麼,要轉換車,你只需要做one_car = FastCar(one_car)。請注意,這不會影響對原始Car對象的引用,Car對象仍將指向同一輛Car。

2
class FastCar(Car): 
    def __init__(self, color, max_speed=100): 
     Car.__init__(self, color) 
     self.max_speed = max_speed 

    def drive_fast(self): 
     print "Driving at %s mph" %self.max_speed 

    @staticmethod 
    def fromOtherCar(car): 
     return FastCar(car.color) 

actually_fast = FastCar.fromOtherCar(thought_was_classic) 

這是標準的方法。

根據實際客艙佈局,你可以做一些事情,如:

classic = Car('blue') 

classic.__class__ = FastCar 
classic.__dict__.update(FastCar(classic.color).__dict__) 

classic.drive_fast() 

但我不會推薦它 - 這是一個黑客,它並不總是可行的,另方式更清潔。

編輯:剛剛添加@ PaulMcGuire的評論說。遵循這個建議,他是對的。

0

爲什麼不僅僅使用一個類?

class Car(object): 
    def __init__(self, color, max_speed = 50): 
     self.color = color 
     self.max_speed = max_speed 
    def drive(self): 
     print "Driving at %s mph"%self.max_speed 

c=Car('blue') 
c.max_speed = 100 
0

在實例化之後,在OOP中改變活體的類型(類)是不常見的。我知道幾乎不會有兩種語言可以作爲骯髒的破解。類型(類)的全部目的是事先知道一個對象可以執行什麼操作,不能執行什麼操作。如果你想要這樣的東西,你可能會誤認爲OOP的想法。

+0

如果您是OOP的新手,我想您可能會考慮從字符數組中創建一個字符串來更改對象的類型。它從舊內容中創造出一個新對象,這是他真正想做的事(他只是不知道它)。 – agf

+0

謝謝,但我不認爲這是我想要做的。我真的不想創建一個新的對象。 – Andy