你可以通过扩展ABC(抽象基类)来创建一个抽象类,并且可以在抽象类中使用@abstractmethod创建抽象方法,如下所示:
from abc import ABC, abstractmethod
class Animal(ABC):
@abstractmethod
def sound(self):
pass
并且,要使用抽象类,它应该由子类扩展,并且子类应该覆盖抽象类的抽象方法,如下所示:
from abc import ABC, abstractmethod
class Animal(ABC):
@abstractmethod
def sound(self):
pass
class Cat(Animal): # Extends "Animal" abstract class
def sound(self): # Overrides "sound()" abstract method
print("Meow!!")
obj = Cat()
obj.sound()
输出:
Meow!!
并且,抽象方法可以有code而不是pass,并且可以由子类调用,如下所示:
from abc import ABC, abstractmethod
class Animal(ABC):
@abstractmethod
def sound(self):
print("Wow!!") # Here
class Cat(Animal):
def sound(self):
super().sound() # Here
obj = Cat()
obj.sound()
输出:
Wow!!
而且,抽象类可以有变量和非抽象方法,可以由子类调用,非抽象方法不需要被子类覆盖,如下所示:
from abc import ABC, abstractmethod
class Animal(ABC):
@abstractmethod
def sound(self):
pass
def __init__(self): # Here
self.name = "John" # Here
x = "Hello" # Here
def test1(self): # Here
print("Test1")
@classmethod # Here
def test2(cls):
print("Test2")
@staticmethod # Here
def test3():
print("Test3")
class Cat(Animal):
def sound(self):
print(self.name) # Here
print(super().x) # Here
super().test1() # Here
super().test2() # Here
super().test3() # Here
obj = Cat()
obj.sound()
输出:
John
Hello
Test1
Test2
Test3
并且,您可以在抽象类中定义抽象类和静态方法以及抽象getter、setter和delete,如下所示。*@abstractmethod必须是最内部的装饰器,否则会发生错误,你可以看到我的回答,解释了更多关于抽象的getter, setter和delete:
from abc import ABC, abstractmethod
class Person(ABC):
@classmethod
@abstractmethod # The innermost decorator
def test1(cls):
pass
@staticmethod
@abstractmethod # The innermost decorator
def test2():
pass
@property
@abstractmethod # The innermost decorator
def name(self):
pass
@name.setter
@abstractmethod # The innermost decorator
def name(self, name):
pass
@name.deleter
@abstractmethod # The innermost decorator
def name(self):
pass
然后,你需要在子类中重写它们,如下所示:
class Student(Person):
def __init__(self, name):
self._name = name
@classmethod
def test1(cls): # Overrides abstract class method
print("Test1")
@staticmethod
def test2(): # Overrides abstract static method
print("Test2")
@property
def name(self): # Overrides abstract getter
return self._name
@name.setter
def name(self, name): # Overrides abstract setter
self._name = name
@name.deleter
def name(self): # Overrides abstract deleter
del self._name
然后,你可以实例化子类并调用它们,如下所示:
obj = Student("John") # Instantiates "Student" class
obj.test1() # Class method
obj.test2() # Static method
print(obj.name) # Getter
obj.name = "Tom" # Setter
print(obj.name) # Getter
del obj.name # Deleter
print(hasattr(obj, "name"))
输出:
Test1
Test2
John
Tom
False
并且,如果你尝试实例化一个抽象类,如下所示:
from abc import ABC, abstractmethod
class Animal(ABC):
@abstractmethod
def sound(self):
pass
obj = Animal()
出现以下错误:
不能实例化抽象类Animal与抽象方法sound
并且,如果你没有在子类中重写抽象类的抽象方法,并且你实例化了子类,如下所示:
from abc import ABC, abstractmethod
class Animal(ABC):
@abstractmethod
def sound(self):
pass
class Cat(Animal):
pass # Doesn't override "sound()" abstract method
obj = Cat() # Here
出现以下错误:
不能用抽象方法实例化抽象类Cat
并且,如果你在非抽象类中定义了一个抽象方法,它没有扩展ABC,那么抽象方法是一个正常的实例方法,所以即使非抽象类被实例化,即使子类没有覆盖非抽象类的抽象方法,也不会出现错误,如下所示:
from abc import ABC, abstractmethod
class Animal: # Doesn't extend "ABC"
@abstractmethod # Here
def sound(self):
print("Wow!!")
class Cat(Animal):
pass # Doesn't override "sound()" abstract method
obj1 = Animal() # Here
obj1.sound()
obj2 = Cat() # Here
obj2.sound()
输出:
Wow!!
Wow!!
另外,你可以替换Cat类扩展下面的Animal class:
from abc import ABC, abstractmethod
class Animal(ABC):
@abstractmethod
def sound(self):
pass
# ↓↓↓ Here ↓↓↓
class Cat(Animal):
def sound(self):
print("Meow!!")
# ↑↑↑ Here ↑↑↑
print(issubclass(Cat, Animal))
下面是register()代码:
from abc import ABC, abstractmethod
class Animal(ABC):
@abstractmethod
def sound(self):
pass
# ↓↓↓ Here ↓↓↓
class Cat:
def sound(self):
print("Meow!!")
Animal.register(Cat)
# ↑↑↑ Here ↑↑↑
print(issubclass(Cat, Animal))
然后,上面的两个代码输出下面相同的结果,显示Cat class是Animal class的子类:
True