继承:将基类实例转换为子类实例

时间:2011-08-16 12:23:29

标签: python oop inheritance

我有一个基类的实例,然后我想让它成为这个基类的子类的一个实例。也许我正在以错误的方式解决这个问题,并且在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成为Car的包装器,它会知道如何快速驾驶:我真的希望FastCar扩展Car;

  • 我真的不想在FastCar中使用__new__方法对参数进行一些测试,并决定__new__是否必须返回Car的新实例或实例I给了它(例如:def __new__(cls, color, max_speed=100, baseclassinstance=None))。

4 个答案:

答案 0 :(得分: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的评论所说的内容。按照这个建议,他是对的。

答案 1 :(得分:0)

你可以借用“复制构造函数”的C ++概念来做类似的事情。

允许Car的构造函数获取Car实例,并复制其所有属性。然后FastCar应接受Car实例或FastCar实例。

那么,要转换汽车,你只需one_car = FastCar(one_car)。请注意,这不会影响对原始Car对象的引用,该对象将保持指向同一个Car。

答案 2 :(得分: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

答案 3 :(得分:0)

在OOP中,在实例化后更改生物对象的类型(类)并不常见。我只知道两种语言可以作为脏黑客。类型(类)的整个目的是事先知道对象可以执行和不可执行的操作。如果你想要这样的东西,你可能会误解OOP的想法。