我有以下示例代码:
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,但同时也不会在2中。
现在我想调用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'>
这是不可能的,还是可能,但只是糟糕的设计?如何解决这样的问题?
答案 0 :(得分:6)
您应该实现Abstract Factory pattern,然后您的工厂将根据提供的参数构建您喜欢的任何对象。这样,您的代码将保持清洁和可扩展。
升级解释器版本时,可以删除任何可以直接使用它的hack,因为没有人期望向后兼容性来保留这些东西。
编辑:过了一段时间我不确定你是否应该使用抽象工厂或Factory Method pattern。这取决于您的代码的详细信息,以满足您的需求。
答案 1 :(得分:2)
通常,当超类知道子类时,这不是一个好主意。
从OO的角度思考你想做什么。
超类为该类型的所有对象提供通用行为,例如动物。然后子类提供行为的特化,例如,狗。
根据“isa”关系来考虑它,即狗是动物。
动物是一只狗真的没有意义。
HTH
欢呼声,
罗布
答案 2 :(得分:2)
我认为您不能更改对象的类型,但您可以创建另一个类,它将像子类的工厂一样工作。像这样:
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)
...