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

3 投票
4 回答
2282 浏览
提问于 2025-04-16 23:41

我有一个基类的实例,然后我想把它变成这个基类的一个子类的实例。也许我对这个问题的理解有点偏差,可能在面向对象编程(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 实例,还是返回我给它的那个实例(例如:def __new__(cls, color, max_speed=100, baseclassinstance=None))。

4 个回答

0

你可以借用C++中的“复制构造函数”这个概念来实现类似的功能。

让汽车(Car)的构造函数可以接收一个汽车实例,并复制它的所有属性。快速汽车(FastCar)应该能够接受汽车实例或者快速汽车实例。

所以,要把一辆普通汽车转换成快速汽车,你只需要这样做:one_car = FastCar(one_car)。需要注意的是,这样做不会影响对原始汽车对象的引用,原来的汽车对象仍然会指向同一辆车。

0

在面向对象编程(OOP)中,改变一个已经创建好的对象的类型(类)并不常见。我只知道两种语言可以这样做,但这算是一种“脏黑客”手法。类型(类)的主要目的是让我们在使用对象之前就知道它能做什么,不能做什么。如果你想这样做,可能是对面向对象编程的理解有些误区。

3
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评论中提到的内容。听从他的建议,他说得对。

撰写回答