2011-08-16 7 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を拡張することを望んでいる。 (:def __new__(cls, color, max_speed=100, baseclassinstance=None)例)

  • は、私は本当に__new__は車の新しいインスタンスまたは私はそれに与えたインスタンスを返すことがある場合は、引数にいくつかのテストを行い、決定するFastCarで__new__メソッドを使用する必要はありません。

+0

なぜあなたはどうしますか?one_car = FastCar(one_car.color、120)?それは本当に遺産ではありませんが、うまくいくはずです。 – Bogdan

+3

あなたのOOPデザインはちょっとしたようです。私はFastCarもdrive()を実装すると思いますが、より速い速度(drive_fastとして実装したもの)でそうするでしょう。あなたが今持っているものでは、呼び出し元は、同じメソッドを呼び出すのではなく、そのメソッドを適切に実装する(良い)のではなく、呼び出すメソッドを知るために型を知っている必要があります。また、FastCarクラスの最後に 'drive = drive_fast'を追加するだけで、これを行うことができます。 – PaulMcG

+0

より良い例: 'FastCar'は' drive_fast'メソッドを持たず、 'Car'のために存在しない' overtake'メソッドです。 – Andy

答えて

0

「コピーコンストラクタ」のC++概念を借りて、このようなことを行うことができます。

CarのコンストラクタがCarインスタンスを受け取り、すべてのプロパティをコピーできるようにします。 FastCarはCarインスタンスまたはFastCarインスタンスのいずれかを受け入れます。

それで、車を変換するには、one_car = FastCar(one_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

ただ1つのクラスを使用するのはなぜですか?

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では一般的ではありません。私はそれほど2つの言語を知っているので、汚れたハックとしてそれを許します。型(クラス)の全目的は、オブジェクトが実行できる操作と実行できない操作を事前に知ることです。このようなことをしたいのであれば、おそらくOOPの考え方を間違っているでしょう。

+0

OOPの初心者だったら、文字配列から文字列を作成してオブジェクトの種類を変更すると思うかもしれません。それは、彼が本当にやりたいことです(彼はそれを知らない)古いものの内容から新しいオブジェクトを作っています。 – agf

+0

ありがとうございますが、私はこれをやりたいとは思いません。私は本当に新しいオブジェクトを作成したくありません。 – Andy

関連する問題