9

I have read that this is the best way to implement an abstract class in Python (as opposed to the abc module):

class Animal(object):
    def speak(self):
        raise NotImplementedError()

class Duck(Animal):
    def speak(self):
        print("quack")

class Cat(Animal):
    def speak(self):
        print("meow")

However, should I use abstract classes? Should I or should I not just use one less class like so:

class Duck(object):
    def speak(self):
        print("quack")

class Cat(Animal):
    def speak(self):
        print("meow")
4

5 回答 5

5

这个问题没有一个答案。您需要动物类型之间的一致接口吗?然后某种抽象基类会很有用,无论它是否来自abc。如果鸭子是唯一的动物,或者它们之间几乎没有相似之处,那么几乎没有什么意义。

于 2013-10-11T14:09:10.683 回答
4

如果所有功能都存在于具体类中——就像你的例子中的情况——我认为拥有基类没有任何好处。

但是,如果某些功能可以由子类共享(即并非所有Animal的方法都是抽象的),那么人们可能会争辩说拥有一个公共基类将是有益的。然后可以将通用功能放入基类并由子类自动共享。

于 2013-10-11T14:10:32.057 回答
1

旁注:在强类型语言中,通用接口的抽象类的很多原因是为了满足类型系统,即如果你想要类似的东西

int myfunc(Animal)

你寄了

int myfunc(Duck)

这只有在 Duck 实际上是 Animal 的子类时才有效,即使接口是相同的;否则它将在不匹配的类型上引发编译器错误。

在python中,python不关心类型是什么,只关心你访问的属性或方法是否存在。所以很多这样的情况不再绝对需要基类。但恕我直言,这仍然是一个好主意,因为您可以使用函数“这需要一个动物”,而不是“这需要 A、B、C 类之一”或(更糟糕的是)“这需要一个实现 x 的对象, y,z 具有这些签名的函数。以后更容易阅读,其他人也更容易使用。

于 2013-10-11T15:09:10.860 回答
1

这取决于你想要做什么。例如,如果您打算拥有许多其他动物类别(狗、猫、狐狸),并且您希望它们都执行一些标准程序(例如,跑来跑去一段时间,然后说出它们特定的声音),那么让抽象超类对于避免重复代码很有用。

于 2013-10-11T14:11:36.613 回答
1

如果你只有一个 Duck 类并且这是你唯一拥有的 Animal 类型,那么拥有一个 Animal 类可能不值得付出额外的努力。另一方面,如果您要拥有多种动物并且需要一种通用的方式来与所有动物交互而不关心它是哪种类型的动物,那么抽象类是有用的。这实际上取决于您正在从事的项目。

于 2013-10-11T14:12:00.320 回答