我能从超类实例化子类对象吗

2024-10-01 11:32:05 发布

您现在位置:Python中文网/ 问答频道 /正文

我有以下示例代码:

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

使用时,可以生成以下内容:

^{pr2}$

现在假设我有更多的子类class C(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'>

这是不可能的还是有可能的只是糟糕的设计?这样的问题该怎么解决?在


Tags: 代码selfid示例fooinitmaindef
3条回答

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

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)
...

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

当您升级解释器版本时,您可以直接使用的任何黑客攻击都可以删除,因为没有人希望向后兼容来保留这些东西。在

编辑:过了一段时间,我不确定您是应该使用抽象工厂,还是Factory Method pattern。它取决于代码的细节,所以适合您的需要。在

一般来说,当一个超类有任何子类的知识时,这不是一个好主意。在

从OO的角度考虑您想做什么。在

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

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

动物就是狗是没有道理的。在

高温

干杯

罗布

相关问题 更多 >