Reputation: 31
I have an instance of a base class, and then I want to make it an instance of a child class of this base class. Maybe I'm taking the problem in a wrong way and there's something important I didn't understand in OOP. Code is only there to illustrate and a very different approach can be suggested. Any help appreciated.
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.
I see a very similar question, but none of the answers suits my problem :
I don't want to make FastCar a wrapper around Car which would know how to drive fast : I really want that FastCar extends Car ;
I don't really want to use the __new__
method in FastCar to make some tests on the arguments and decide if __new__
has to return a new instance of Car or the instance I gave to it (example: def __new__(cls, color, max_speed=100, baseclassinstance=None)
).
Upvotes: 3
Views: 2372
Reputation: 176780
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)
This is the standard way.
Depending on the real class layout, you may be able to do something like:
classic = Car('blue')
classic.__class__ = FastCar
classic.__dict__.update(FastCar(classic.color).__dict__)
classic.drive_fast()
But I wouldn't recommend it -- it's a hack, it won't always work, and the other way is cleaner.
Edit: Was just about to add basically what @PaulMcGuire's comment says. Follow that advice, he's right.
Upvotes: 3
Reputation: 24439
It is not common in OOP to change type (class) of a living object after instantiation. I know barely two languages that would allow that as a dirty hack. The whole purpose of types (classes) is to know beforehand what operations an object can and can not perform. If you want something like this, you're probably mistaking the idea of OOP.
Upvotes: 0
Reputation: 879591
Why not just use one class?
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
Upvotes: 0
Reputation: 169018
You can borrow the C++ notion of a "copy constructor" to do something like this.
Allow Car's constructor to take a Car instance, and copy all of its properties. FastCar should then accept either Car instances or FastCar instances.
So then, to convert the car, you would just do one_car = FastCar(one_car)
. Note that this will not affect references to the original Car object, which will remain pointing to the same Car.
Upvotes: 0