继承:将基类实例转换为子类实例
我有一个基类的实例,然后我想把它变成这个基类的一个子类的实例。也许我对这个问题的理解有点偏差,可能在面向对象编程(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 个回答
你可以借用C++中的“复制构造函数”这个概念来实现类似的功能。
让汽车(Car)的构造函数可以接收一个汽车实例,并复制它的所有属性。快速汽车(FastCar)应该能够接受汽车实例或者快速汽车实例。
所以,要把一辆普通汽车转换成快速汽车,你只需要这样做:one_car = FastCar(one_car)
。需要注意的是,这样做不会影响对原始汽车对象的引用,原来的汽车对象仍然会指向同一辆车。
在面向对象编程(OOP)中,改变一个已经创建好的对象的类型(类)并不常见。我只知道两种语言可以这样做,但这算是一种“脏黑客”手法。类型(类)的主要目的是让我们在使用对象之前就知道它能做什么,不能做什么。如果你想这样做,可能是对面向对象编程的理解有些误区。
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评论中提到的内容。听从他的建议,他说得对。