Python中抽象方法的继承

5

假设我们有一个使用abc模块定义抽象属性的Python类:

import abc

class A(object):
    __metaclass__ = abc.ABCMeta

    @abc.abstractproperty
    def test_attribute(self):
        raise NotImplementedError

现在我们考虑定义一个从A子类化的B,通过添加一个新方法(test_method()),以及一个从B子类化的C来实现在A中原先声明的抽象方法:

class B(A):

    def test_method(self):
        pass

class C(B):

    def test_attribute(self):
        # Implement abstract attribute
        pass

假设我想保持B的抽象(不可实例化),那么我应该重新定义B中的抽象属性(test_attribute)和元类分配吗?还是从A继承它们就足够了(如上述代码)?
我知道Python允许我不重新定义抽象方法,因此可以从父类继承。这在理论软件工程角度来说是正确的吗?
我之所以问这个问题,是因为如果我没有错的话其他语言(如Java)不允许在不重新实现为抽象的情况下继承抽象方法...

只要子类是抽象的(或者是扩展另一个接口的接口),在Java中就可以很好地继承抽象方法,而不需要重新实现它们。其他语言(如Java)不允许继承抽象方法而不将它们重新实现为抽象方法。 - user2357112
1个回答

5
你已经几乎完成了所有代码,你可以进行测试并查看它是否有效...但是作为一个提示,只要C.test_attribute被装饰为property,那么你的设计就很好。
如果你尝试创建B的实例,则会遇到问题,因为整个抽象接口尚未创建,但将其创建为C(以及后来可能的其他类)的基类是可以的。
例如:
import abc

class A(object):
  __metaclass__ = abc.ABCMeta

  @abc.abstractproperty
  def foo(self):
    pass

class B(A):
  def bar(self):
    return "bar"

class C(B):
  @property
  def foo(self):
    return "foo"

print C().foo    # foo
print C().bar()  # bar
print B().foo    # TypeError

@Andrea:__metaclass__与其他类属性没有任何区别,因此会从父类继承(在多重继承的情况下,如果父类有不同的元类,则有规则确定哪个元类实际用于创建子类)。 - chepner
@chepner -- 注意解释的准确性。在Python3.x中,没有__metaclass__属性,它的工作方式不同... - mgilson
是的。然而,在Python 3中,使用“元类”关键字设置新类的“__class__”属性,然后该属性被子类继承。 - chepner

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接