可以实例化一个子类对象从超

问题描述:

我有以下示例代码:可以实例化一个子类对象从超

class A(object): 
    def __init__(self, id): 
     self.myid = id 
    def foo(self, x): 
     print 'foo', self.myid*x 

class B(A): 
    def __init__(self, id): 
     self.myid = id 
     self.mybid = id*2 
    def bar(self, x): 
     print 'bar', self.myid, self.mybid, x 

使用时,以下可能产生:

>>> a = A(2) 
>>> a.foo(10) 
foo 20 
>>> 
>>> b = B(3) 
>>> b.foo(10) 
foo 30 
>>> b.bar(12) 
bar 3 6 12 

现在可以说我有一些子类class C(A):class D(A):。我也知道id始终适合B,C或D,但从来不会同时在其中两个。

现在我想调用A(23)并获得正确子类的对象。事情是这样的:

>>> type(A(2)) 
<class '__main__.B'> 
>>> type(A(22)) 
<class '__main__.D'> 
>>> type(A(31)) 
<class '__main__.C'> 
>>> type(A(12)) 
<class '__main__.B'> 

这是不可能的或者是可能的,但只是糟糕的设计?这样的问题应该如何解决?

您应该实施Abstract Factory pattern,然后您的工厂将根据提供的参数构建您喜欢的任何对象。这样你的代码将保持干净和可扩展。

当你升级你的解释器版本时,你可以直接使用的任何破解都可以被删除,因为没有人需要向后兼容性来保存这些东西。

编辑:一段时间后,我不知道你是否应该使用抽象工厂,或Factory Method pattern。这取决于您的代码的细节,以满足您的需求。

当超类具有子类的任何知识时,通常不是一个好主意。

从OO的角度思考你想做什么。

超类为所有类型的对象提供共同行为,例如,动物。然后,该子类提供行为的专门化,例如狗。

从“isa”关系的角度考虑,即狗是动物。

动物是一只狗并不真正有意义。

HTH

欢呼声,

罗布

我不认为你可以改变对象的类型,但你可以创建另一个类,将工作就像一个工厂的子类。像这样的:

class LetterFactory(object): 
    @staticmethod 
    def getLetterObject(n): 
     if n == 1: 
      return A(n) 
     elif n == 2: 
      return B(n) 
     else: 
      return C(n) 

a = LetterFactory.getLetterObject(1) 
b = LetterFactory.getLetterObject(2) 
... 
+0

我不知道为什么LetterFactory必须是一个类。将其定义为`letter_factory`函数会使事情变得更容易(例如,不需要`LetterFactory.getLetterObject`调用,只需调用`letter_factory`) – tzot 2009-10-27 10:04:55