【问题标题】:Initializing a Subclass Instance from a Superclass Object从超类对象初始化子类实例
【发布时间】:2016-06-13 01:35:36
【问题描述】:

logging.Logger 的文档指出:

请注意,Logger 永远不会直接实例化,而是始终通过模块级函数 logging.getLogger(name)

这让我想到了以下问题(我将切换到一些Foo 类而不是logging.Logger,因为我想问一下一般的原理)。


假设有一些类Foo,有几个属性和方法:

class Foo:
    def method_0(self..):
        ...

    def method_1(self..):
        ...

    def method_n(self..):
        ...

我想继承Foo,并且只专门化其中的几个方法。

class SubFoo(Foo):
    def method_1(self, ...):
        ...
        # Or super - not the point of the question.
        Foo.method_1(self, ...)

    ...

问题在于Foo 没有可用的构造函数,只有创建Foo 类型对象的方法,例如通过getFooSubFoo 的“Foo”部分需要是“已批准”Foo 对象,我不知道如何强制将 SubFoos Foo 部分设为“已批准”对象。

注意

对于Foo 的子类化显然有几个解决方法,例如,组合、猴子修补、与__dict__/gettatr 的巧妙游戏等。尽管如此,这个问题是关于子类化的。

【问题讨论】:

标签: python inheritance constructor


【解决方案1】:

您误解了继承。要创建 SubFoo 的实例,您只需像对任何其他类一样实例化它:SubFoo()

Python 没有构造函数,在任何情况下,未在子类上定义的方法都会自动继承超类版本,而无需您做任何事情。

【讨论】:

  • 谢谢,但我真的不明白你的回答。当我对某些东西进行子类化时,我的子类的代码__init__(我显然错误地称为ctor)调用超类的__init__(使用super,或其他方式)。我不明白当我在这里调用SubFoo 时,如何创建一个Foo 对象(不过,我确实知道如何通过组合来实现它——我只会调用getLogger 的等价物)。跨度>
  • 不会,会创建一个 SubFoo。这就是继承的意义:一个 SubFoo is-a Foo.
  • 非常感谢,我现在明白你的回答了。不过,重点仍然是,我不是从超类实例创建子类实例,不是吗?大概 getLogger 有一些副作用(如果没有,我假设的 getFoo 有),所以我必须用一些“批准”的超类对象来实例化它。
  • 尽管如此,感谢关于超类的 init 与 Liskov is-a 模糊不清的更正。赞赏。
猜你喜欢
  • 2012-04-27
  • 2019-05-09
  • 2018-08-14
  • 2013-02-11
  • 2013-07-27
  • 1970-01-01
  • 2013-04-14
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多