返回子类实例的父方法

时间:2014-09-25 08:18:10

标签: python class oop

这是不好的做法,如果是这样,为什么要返回子类的实例作为父类实例的方法的输出?

例如,可以进行以下操作 -

class Parent(object):
    def __init__(self, attr):
        self.attr = attr

    def child(self, typ):
        if typ == 'a':
            return ChildA(self.attr)
        else:
            return ChildB(self.attr)

class ChildA(Parent):
    pass

class ChildB(Parent):
    pass

是个好设计吗?

1 个答案:

答案 0 :(得分:3)

我期待有更多知识渊博的人回答这个问题,但由于这还没有发生,我会投入两美分的价值。我将尝试解决此类设计的技术问题,并为专业人员提供更高级别的分析。

我认为这确实不是好习惯。由于多种原因,父类不应该知道子类,但首先它使得将来扩展模块变得更加困难。每当新的子类继承父类(或其子类)时,它可能也需要更新父类。在Python中,它强制在同一个文件中定义所有未来的子类,以避免循环导入。虽然这两个问题都可能被规避,但这似乎是不必要的麻烦。

此外,由于指定的方法是在子类中继承的,因此除非它被覆盖,否则它会触发“兄弟”类之间的某种熟悉,这可能是不希望的。

虽然我确定在某些情况下父类会发现其子类似乎有用,但我认为一般情况下,这种情况会导致设计中的错误和不具备的替代解决方案。涉及这种内省应该受到追捧。

请注意,这并不意味着父对象不应该知道子对象。与任何其他对象一样,子对象可以合法地作为参数在父方法中工作。父对象甚至可以将它们视为父对象,因为子对象也是父对象,这是OOP的主要要点之一。

关于您的特定示例,可以通过factory design pattern来实现。创建的对象不需要与其创建者的实例相同。例如:

class factory(object):
    def __init__(self, attr):
        self.attr = attr

    def create(self, typ)
        if typ == 'a':
            return ChildA(self.attr)
        else:
            return ChildB(self.attr)

class Parent(object):
    def __init__(self, attr):
        self.attr = attr

class ChildA(Parent):
    pass

class ChildB(Parent):
    pass