📜  Python中的抽象类

📅  最后修改于: 2022-05-13 01:55:06.785000             🧑  作者: Mango

Python中的抽象类

一个抽象类可以被认为是其他类的蓝图。它允许您创建一组必须在从抽象类构建的任何子类中创建的方法。包含一个或多个抽象方法的类称为抽象类。抽象方法是具有声明但没有实现的方法。在设计大型功能单元时,我们使用抽象类。当我们想为组件的不同实现提供通用接口时,我们使用抽象类。为什么使用抽象基类:
通过定义一个抽象基类,您可以为一组子类定义一个通用的应用程序接口(API)。此功能在第三方将提供实现的情况下特别有用,例如使用插件,但也可以在大型团队或大型代码库中为您提供帮助,因为您很难记住所有类或不可能。抽象基类如何工作:
默认情况下, Python不提供抽象类。 Python附带一个模块,该模块为定义抽象基类(ABC)提供了基础,该模块名称为 ABC。 ABC的工作方式是将基类的方法装饰为抽象,然后将具体类注册为抽象基的实现。当使用关键字@abstractmethod 修饰时,方法变得抽象。例如 -

代码 1:

Python3
# Python program showing
# abstract base class work
 
from abc import ABC, abstractmethod
 
class Polygon(ABC):
 
    @abstractmethod
    def noofsides(self):
        pass
 
class Triangle(Polygon):
 
    # overriding abstract method
    def noofsides(self):
        print("I have 3 sides")
 
class Pentagon(Polygon):
 
    # overriding abstract method
    def noofsides(self):
        print("I have 5 sides")
 
class Hexagon(Polygon):
 
    # overriding abstract method
    def noofsides(self):
        print("I have 6 sides")
 
class Quadrilateral(Polygon):
 
    # overriding abstract method
    def noofsides(self):
        print("I have 4 sides")
 
# Driver code
R = Triangle()
R.noofsides()
 
K = Quadrilateral()
K.noofsides()
 
R = Pentagon()
R.noofsides()
 
K = Hexagon()
K.noofsides()


Python3
# Python program showing
# abstract base class work
 
from abc import ABC, abstractmethod
class Animal(ABC):
 
    def move(self):
        pass
 
class Human(Animal):
 
    def move(self):
        print("I can walk and run")
 
class Snake(Animal):
 
    def move(self):
        print("I can crawl")
 
class Dog(Animal):
 
    def move(self):
        print("I can bark")
 
class Lion(Animal):
 
    def move(self):
        print("I can roar")
         
# Driver code
R = Human()
R.move()
 
K = Snake()
K.move()
 
R = Dog()
R.move()
 
K = Lion()
K.move()


Python3
# Python program showing
# implementation of abstract
# class through subclassing
 
import abc
 
class parent:      
    def geeks(self):
        pass
 
class child(parent):
    def geeks(self):
        print("child class")
 
# Driver code
print( issubclass(child, parent))
print( isinstance(child(), parent))


Python3
# Python program invoking a
# method using super()
 
import abc
from abc import ABC, abstractmethod
 
class R(ABC):
    def rk(self):
        print("Abstract Base Class")
 
class K(R):
    def rk(self):
        super().rk()
        print("subclass ")
 
# Driver code
r = K()
r.rk()


Python3
# Python program showing
# abstract properties
 
import abc
from abc import ABC, abstractmethod
 
class parent(ABC):
    @abc.abstractproperty
    def geeks(self):
        return "parent class"
class child(parent):
      
    @property
    def geeks(self):
        return "child class"
  
  
try:
    r =parent()
    print( r.geeks)
except Exception as err:
    print (err)
  
r = child()
print (r.geeks)


Python3
# Python program showing
# abstract class cannot
# be an instantiation
from abc import ABC,abstractmethod
 
class Animal(ABC):
    @abstractmethod
    def move(self):
        pass
class Human(Animal):
    def move(self):
        print("I can walk and run")
 
class Snake(Animal):
    def move(self):
        print("I can crawl")
 
class Dog(Animal):
    def move(self):
        print("I can bark")
 
class Lion(Animal):
    def move(self):
        print("I can roar")
 
c=Animal()


输出:

I have 3 sides
I have 4 sides
I have 5 sides
I have 6 sides


代码 2:

Python3

# Python program showing
# abstract base class work
 
from abc import ABC, abstractmethod
class Animal(ABC):
 
    def move(self):
        pass
 
class Human(Animal):
 
    def move(self):
        print("I can walk and run")
 
class Snake(Animal):
 
    def move(self):
        print("I can crawl")
 
class Dog(Animal):
 
    def move(self):
        print("I can bark")
 
class Lion(Animal):
 
    def move(self):
        print("I can roar")
         
# Driver code
R = Human()
R.move()
 
K = Snake()
K.move()
 
R = Dog()
R.move()
 
K = Lion()
K.move()

输出:

I can walk and run
I can crawl
I can bark
I can roar


通过子类化实现:
通过直接从基类子类化,我们可以避免显式注册类的需要。在这种情况下, Python类管理用于将PluginImplementation识别为实现抽象 PluginBase。

Python3

# Python program showing
# implementation of abstract
# class through subclassing
 
import abc
 
class parent:      
    def geeks(self):
        pass
 
class child(parent):
    def geeks(self):
        print("child class")
 
# Driver code
print( issubclass(child, parent))
print( isinstance(child(), parent))

输出:

True
True

使用直接子类化的一个副作用是,可以通过向基类询问从它派生的已知类的列表来找到插件的所有实现。抽象基类中的具体方法:
具体类只包含具体(普通)方法,而抽象类可能同时包含具体方法和抽象方法。具体类提供抽象方法的实现,抽象基类也可以通过 super() 调用方法来提供实现。

让我们看一下使用 super() 调用方法的示例:

Python3

# Python program invoking a
# method using super()
 
import abc
from abc import ABC, abstractmethod
 
class R(ABC):
    def rk(self):
        print("Abstract Base Class")
 
class K(R):
    def rk(self):
        super().rk()
        print("subclass ")
 
# Driver code
r = K()
r.rk()

输出:

Abstract Base Class
subclass

在上面的程序中,我们可以使用 super() 来调用抽象类中的方法。抽象属性:
抽象类除了方法之外还包括属性,您可以通过使用@abstractproperty 定义具体类中的属性。

Python3

# Python program showing
# abstract properties
 
import abc
from abc import ABC, abstractmethod
 
class parent(ABC):
    @abc.abstractproperty
    def geeks(self):
        return "parent class"
class child(parent):
      
    @property
    def geeks(self):
        return "child class"
  
  
try:
    r =parent()
    print( r.geeks)
except Exception as err:
    print (err)
  
r = child()
print (r.geeks)

输出:

Can't instantiate abstract class parent with abstract methods geeks
child class

在上面的示例中,无法实例化 Base 类,因为它只有属性 getter 方法的抽象版本。抽象类实例化:
抽象类是不完整的,因为它们有没有人的方法。如果Python允许为抽象类创建对象,那么如果有人调用抽象方法,则使用该对象,但没有要调用的实际实现。所以我们使用一个抽象类作为模板,并根据需要,在使用它之前对其进行扩展和构建。由于事实上,抽象类不是具体类,它不能被实例化。当我们为抽象类创建对象时,它会引发错误

Python3

# Python program showing
# abstract class cannot
# be an instantiation
from abc import ABC,abstractmethod
 
class Animal(ABC):
    @abstractmethod
    def move(self):
        pass
class Human(Animal):
    def move(self):
        print("I can walk and run")
 
class Snake(Animal):
    def move(self):
        print("I can crawl")
 
class Dog(Animal):
    def move(self):
        print("I can bark")
 
class Lion(Animal):
    def move(self):
        print("I can roar")
 
c=Animal()

输出:

Traceback (most recent call last):
  File "/home/ffe4267d930f204512b7f501bb1bc489.py", line 19, in 
    c=Animal()
TypeError: Can't instantiate abstract class Animal with abstract methods move