Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/oop/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 我可以从超类实例化子类对象吗_Python_Oop - Fatal编程技术网

Python 我可以从超类实例化子类对象吗

Python 我可以从超类实例化子类对象吗,python,oop,Python,Oop,我有以下示例代码: 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):

我有以下示例代码:

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
现在让我们假设我还有一些子类
类C(A):
类D(A):
。我也知道id将始终适合B、C或D,但决不能同时适合其中两个

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

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)
...
>类型(A(2))
>>>类型(A(22))
>>>类型(A(31))
>>>类型(A(12))

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

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

当您升级解释器版本时,可以删除任何可以直接使用的hack,因为没有人期望向后兼容来保留这些东西


编辑:过了一段时间,我不确定是否应该使用抽象工厂,或者。这取决于代码的细节,因此适合您的需要。

一般来说,当超类了解子类时,这不是一个好主意

从面向对象的角度考虑你想做什么

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

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

动物就是狗,这是没有道理的

干杯


Rob

我不认为您可以更改对象的类型,但是您可以创建另一个类,该类的工作方式类似于子类的工厂。大概是这样的:

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

我不知道为什么LetterFactory必须是一个类。将其定义为
letter\u factory
函数将使事情变得更简单(例如,不需要
LetterFactory.getletletobject
调用,只需
letter\u factory
调用)