跳至主要内容

抽象类

Abstract Classes in Python

在面向对象编程中,抽象类是一种无法实例化且设计为子类的类,为其派生类提供基本接口。Python 是一种面向对象语言,通过其 抽象基类 (ABC) 模块支持抽象类。此模块提供了一种定义抽象类并在其子类上强制执行其接口的方法。本文将探讨 Python 中的抽象类 的概念,以及如何使用 Python 抽象基类实现它们。

Python 抽象类的简介

在 Python 中,抽象类是一种设计为由其他类继承的类。它无法自行实例化,其目的是为其他类构建提供模板。

Python 中的抽象基类使用 abc 模块定义。它允许我们指定一个类必须实现特定方法,但它不为这些方法提供实现。从抽象基类继承的任何类都必须实现所有抽象方法。

from abc import ABC, abstractmethod

class Shape(ABC):
    @abstractmethod
    def area(self):
        pass

class Rectangle(Shape):
    def __init__(self, width, height):
        self.width = width
        self.height = height

    def area(self):
        return self.width * self.height

r = Rectangle(5, 6)
print(r.area())    ### Output 30

在上面的示例中,Shape 是一个抽象基类,定义了一个抽象方法 areaRectangle 是一个从 Shape 继承并实现 area 方法的具体类。

from abc import ABC, abstractmethod

class Animal(ABC):
    @abstractmethod
    def talk(self):
        pass

class Dog(Animal):
    def talk(self):
        return "Woof!"

class Cat(Animal):
    def talk(self):
        return "Meow"

c = Cat()
print(c.talk())    ### Output Meow

d = Dog()
print(d.talk())    ### Output Woof!

在此示例中,Animal 是一个抽象基类,定义了一个抽象方法 talkDogCat 是从 Animal 继承并实现 talk 方法的具体类。

总之,Python 中的抽象类提供了一种为其他类构建提供模板的方法。它们无法自行实例化,并且提供了一种确保子类实现特定方法的方法。abc 模块提供了一种在 Python 中定义抽象基类的方法。

创建 Python 抽象基类

抽象类是一种无法实例化且旨在用作其他类的基类的类。

在 Python 中,abc 模块提供 ABC 类。它用于创建抽象基类。

要创建抽象基类,我们需要从 ABC 类继承并使用 @abstractmethod 装饰器声明抽象方法。

抽象类的示例

from abc import ABC, abstractmethod

class Shape(ABC):

    @abstractmethod
    def area(self):
        pass

    @abstractmethod
    def perimeter(self):
        pass

在此示例中,我们创建了一个具有两个抽象方法 areaperimeter 的抽象基类 Shape。从 Shape 继承的任何类都必须实现这两个方法。

带继承的抽象类的示例


from abc import ABC, abstractmethod

class Animal(ABC):

    @abstractmethod
    def sound(self):
        pass

class Dog(Animal):

    def sound(self):
        return 'Woof'

在此示例中,我们创建了一个抽象基类 Animal,其中包含一个抽象方法 sound。我们还创建了一个类 Dog,它继承自 Animal 并实现了 sound 方法。

继承自抽象基类的类必须实现基类中声明的所有抽象方法,除非它也是一个抽象类。

Python 抽象类与接口

抽象类是一个 Python 类,它不能被实例化,并且用于定义子类可以继承的通用属性和行为。它是使用 abc 模块定义的,该模块代表抽象基类。当我们想要定义一个基类,并且不希望它被实例化时,可以使用抽象类。相反,我们希望它被其他类(这些类将提供其抽象方法的特定实现)子类化。

Python 抽象基类的示例

from abc import ABC, abstractmethod
 
class Animal(ABC):
     
    @abstractmethod
    def move(self):
        pass
 
class Dog(Animal):
     
    def move(self):
        print("I am walking on four legs")
         
class Snake(Animal):
     
    def move(self):
        print("I am slithering")
         
d = Dog()
d.move()
 
s = Snake()
s.move()

在上面的示例中,Animal 是一个抽象基类,其中包含一个称为 move() 的抽象方法。Dog 和 Snake 是 Animal 类的两个子类,它们提供了 move() 方法的特定实现。

Python 中的接口

接口是定义类行为的抽象方法的集合。在 Python 中,没有像 Java 等其他编程语言中那样的接口的严格定义。相反,我们使用抽象类来定义接口。可以将接口视为类和外部世界之间的契约。实现接口的类必须为接口中定义的所有方法提供实现。

Python 接口的示例

from abc import ABC, abstractmethod
 
class Shape(ABC):
     
    @abstractmethod
    def area(self):
        pass
 
    @abstractmethod
    def perimeter(self):
        pass
 
class Rectangle(Shape):
     
    def __init__(self, length, width):
        self.length = length
        self.width = width
     
    def area(self):
        return self.length * self.width
     
    def perimeter(self):
        return 2 * (self.length + self.width)

r = Rectangle(10, 5)
print("Area of Rectangle:", r.area())  # Area of Rectangle: 50
print("Perimeter of Rectangle:", r.perimeter()) # Perimeter of Rectangle: 30

在上面的示例中,Shape 是一个接口,其中包含两个称为 area()perimeter() 的抽象方法。Rectangle 是一个类,它实现了 Shape 接口,并为 area()perimeter() 方法提供了其实现。

Python 抽象类中的多态性

抽象类是一个不能被实例化的类,但它可以用作其他类的基类。它是一种为一组相关类定义通用接口的方法。多态性是指对象可以采用多种形式的能力。在 Python 中,抽象类可用于实现多态性。

from abc import ABC, abstractmethod

class Animal(ABC):
    @abstractmethod
    def move(self):
        pass

class Dog(Animal):
    def move(self):
        print("Dog is running")

class Cat(Animal):
    def move(self):
        print("Cat is jumping")

d = Dog()
c = Cat()

d.move() ### This will print "dog is running"
c.move() ### This will print "cat is jumping"

Python 抽象基类 (ABC) 的用法

Python 中的抽象类是不能被实例化的类,并且旨在被其他类继承。它们对于定义应由其具体子类实现的通用方法和属性非常有用。

在 Python 中实现抽象类的一种方法是从 abc 模块中使用抽象基类 (ABC)。ABC 是一种特殊类型的类,不能直接实例化,但可以进行子类化。ABC 定义了一个或多个抽象方法,这些方法是任何具体子类都必须实现的方法。

以下代码示例演示了如何定义一个抽象基类 Animal,它定义了两个抽象方法 speakmove,任何具体子类都必须实现这两个方法

from abc import ABC, abstractmethod

class Animal(ABC):
    @abstractmethod
    def speak(self):
        pass
    
    @abstractmethod
    def move(self):
        pass

class Cat(Animal):
    def speak(self):
        print('meow')
    
    def move(self):
        print('running')

现在,Animal 的任何具体子类都必须实现 speakmove

在 Python 中使用 ABC 的另一个好处是,它们可用于在类上强制执行某些接口契约,而无需指定其实现细节。

例如,如果你想定义一个函数,该函数仅接受具有 draw 方法的 对象,则可以定义一个称为 Drawable 的 ABC,它定义了一个抽象方法 draw

from abc import ABC, abstractmethod

class Drawable(ABC):
    @abstractmethod
    def draw(self):
        pass
        
def draw_all(drawables):
    for drawable in drawables:
        drawable.draw()

class Rectangle(Drawable):
    def draw(self):
        print('Drawing a rectangle')
    
    
class Circle(Drawable):
    def draw(self):
        print('Drawing a circle')
    
draw_all([Rectangle(), Circle()])

在此示例中,draw_all 函数接受一个 Drawable 对象列表,它通过调用它们的 draw 方法来绘制这些对象。RectangleCircle 类都实现了 draw 方法,因此它们可以与 draw_all 函数一起使用。

总体而言,Python 中的抽象基类通过允许您定义可由具体子类轻松扩展和自定义的通用功能,为代码设计提供了一个强大的工具。

设计 Python 抽象类的最佳实践

在 Python 中设计抽象类时,遵循最佳实践非常重要,以确保代码库的可维护性和可读性。

  1. 使用 abc 模块来定义抽象基类 (ABC)。
import abc

class Shape(metaclass=abc.ABCMeta):
    @abc.abstractmethod
    def area(self):
        pass
    
class Circle(Shape):
    def __init__(self, radius):
        self.radius = radius
        
    def area(self):
        return 3.14 * self.radius ** 2
  1. 使用抽象方法来指定派生类必须遵循的契约。
import abc

class Vehicle(metaclass=abc.ABCMeta):
    @abc.abstractmethod
    def start_engine(self):
        pass
    
class Car(Vehicle):
    def start_engine(self):
        print("Engine started")

class Bike(Vehicle):
    pass

my_car = Car()
my_car.start_engine()    # "Engine started"

# my_bike = Bike()    TypeError: Can't instantiate abstract class Bike with abstract methods start_engine

遵循这些最佳实践将确保您的抽象类易于理解和维护,并且派生类遵循明确的契约。

与我们一起贡献!

不要犹豫,在 GitHub 上为 Python 教程做出贡献:创建一个分支,更新内容并发出拉取请求。

Profile picture for user AliaksandrSumich
Python 工程师,第三方 Web 服务集成专家。
更新:05/03/2024 - 21:52
Profile picture for user angarsky
已审阅并批准