Наследование: преобразование экземпляра базового класса в экземпляр дочернего класса - PullRequest
2 голосов
/ 16 августа 2011

У меня есть экземпляр базового класса, и затем я хочу сделать его экземпляром дочернего класса этого базового класса.Может быть, я неправильно понимаю проблему, и в ООП есть что-то важное, чего я не понял.Код приведен только для иллюстрации, и можно предложить совершенно другой подход.Любая помощь приветствуется.

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Обертка вокруг Car, которая знает, как быстро ездить: я действительно хочу, чтобы FastCar расширял Car;

  • Я действительно не хочу использовать метод __new__ в FastCar для проведения некоторых тестовна аргументах и ​​решите, должен ли __new__ вернуть новый экземпляр Car или экземпляр, который я ему дал (пример: def __new__(cls, color, max_speed=100, baseclassinstance=None)).

Ответы [ 4 ]

2 голосов
/ 16 августа 2011
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 голосов
/ 16 августа 2011

В ООП не принято менять тип (класс) живого объекта после создания экземпляра. Я знаю только два языка, которые допускали бы это как грязный хак . Вся цель типов (классов) состоит в том, чтобы заранее знать, какие операции может и не может выполнять объект. Если вы хотите что-то подобное, вы, вероятно, ошибаетесь в идее ООП.

0 голосов
/ 16 августа 2011

Почему бы просто не использовать один класс?

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 голосов
/ 16 августа 2011

Вы можете позаимствовать понятие C ++ "конструктор копирования", чтобы сделать что-то вроде этого.

Разрешить конструктору Car взять экземпляр Car и скопировать все его свойства.FastCar должен затем принимать экземпляры Car или FastCar.

Итак, чтобы преобразовать автомобиль, вы просто должны сделать one_car = FastCar(one_car).Обратите внимание, что это не повлияет на ссылки на исходный объект Car, который по-прежнему будет указывать на тот же автомобиль.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...