2011-08-16 108 views
2

我有一个基类的实例,然后我想使它成为此基类的子类的实例。也许我以一种错误的方式解决问题,在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围绕汽车的包装,其知道如何开快车:我真的希望FastCar扩展Car;

  • 我真的不希望使用FastCar的__new__方法做出的论点一些测试,并决定是否__new__必须返回车的新实例或者我给它的实例(例如:def __new__(cls, color, max_speed=100, baseclassinstance=None))。

+0

为什么你不这样做:one_car = FastCar(one_car.color,120)?这不是真正的继承或什么,但应该工作。 – Bogdan

+3

您的OOP设计看起来有点不合适。我会想象FastCar也会实现drive(),但是会以更高的速度执行(你已经实现了drive_fast)。用你现在拥有的东西,调用者必须知道类型以知道调用哪个方法(坏),而不是调用相同的方法,并让各种类型适当地实现该方法(良好)。您也可以通过在FastCar类的末尾添加'drive = drive_fast'来完成此操作。 – PaulMcG

+0

好的。一个更好的例子:'FastCar'没有'drive_fast'方法,但是'overtake'方法不存在'Car'。 – Andy

回答

0

您可以借用“复制构造函数”的C++概念来做这样的事情。

允许Car的构造函数采用Car实例,并复制其所有属性。 FastCar应该接受Car实例或FastCar实例。

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

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的评论说。遵循这个建议,他是对的。

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 
0

在实例化之后,在OOP中改变活体的类型(类)是不常见的。我知道几乎不会有两种语言可以作为肮脏的破解。类型(类)的全部目的是事先知道一个对象可以执行什么操作,不能执行什么操作。如果你想要这样的东西,你可能会误认为OOP的想法。

+0

如果您是OOP的新手,我想您可能会考虑从字符数组中创建一个字符串来更改对象的类型。它从旧内容中创造出一个新对象,这是他真正想做的事(他只是不知道它)。 – agf

+0

谢谢,但我不认为这是我想要做的。我真的不想创建一个新的对象。 – Andy