强制子类覆盖父方法

问题描述 投票:25回答:3

假设我有一个带有未实现方法的基类,如下所示:

class Polygon():
    def __init__(self):
        pass

    def perimeter(self):
        pass

    def area(self):
        pass

现在,假设我的一位同事使用Polygon类创建子类,如下所示:

import math

class Circle(Polygon):
    def __init__(self, radius):
        self.radius = radius

    def perimeter(self):
        return 2 * math.pi * self.radius

(H / Sh)e忘记实现area()方法。

如何强制子类实现父的area()方法?

python inheritance method-overriding
3个回答
62
投票

这可能是你的父类:

class Polygon():
    def __init__(self):
        raise NotImplementedError

    def perimeter(self):
        raise NotImplementedError

    def area(self):
        raise NotImplementedError

虽然问题只会在运行时发现,但是当其中一个子类的实例尝试调用其中一种方法时。


另一个版本是使用abc.abstractmethod

from abc import ABCMeta, abstractmethod
# simpler alternative: from abc import ABC, abstractmethod
import math

class Polygon(metaclass=ABCMeta):
# simpler alternative: class Polygon(ABC)

    @abstractmethod
    def __init__(self):
        pass

    @abstractmethod
    def perimeter(self):
        pass

    @abstractmethod
    def area(self):
        pass

class Circle(Polygon):
    def __init__(self, radius):
        self.radius = radius

    def perimeter(self):
        return 2 * math.pi * self.radius

#    def area(self):
#        return math.pi * self.radius**2


c = Circle(9.0)
# TypeError: Can't instantiate abstract class Circle
#            with abstract methods area

如果没有实现所有方法,你将无法实例化Circle

这是python 3语法;在python 2,你需要

class Polygon(object):
    __metaclass__ = ABCMeta

另请注意,对于二进制特殊函数__eq__(), __lt__(), __add__(), ...,最好是return NotImplemented而不是提高NotImplementedError


5
投票

这正是NotImplementedError用于:)

在你的基类中

def area(self):
    raise NotImplementedError("Hey, Don't forget to implement the area!")

4
投票

您可以在基类方法中引发NotImplementedError异常。

class Polygon:
    def area(self):
        raise NotImplementedError

你也可以使用@abc.abstractmethod,但是你需要将metaclass声明为abc.ABCMeta,这将使你的类抽象化。关于abc module的更多信息

© www.soinside.com 2019 - 2024. All rights reserved.