Andy
Andy

Reputation: 31

Inheritance : transform a base class instance to a child class instance

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 :

Upvotes: 3

Views: 2372

Answers (4)

agf
agf

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

hamstergene
hamstergene

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

unutbu
unutbu

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

cdhowie
cdhowie

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

Related Questions