pythonの抽象ベースクラスABC

5898 ワード

pythonの抽象ベースクラス(ABC,Abstract Base Class)はJavaのインタフェースに相当し、抽象ベースクラスは様々なメソッドを定義し、具体的な実装をしなくてもよいクラスであり、もちろん実装も可能であるが、サブクラスが抽象ベースクラスで定義されたメソッドを呼び出すにはsuper()抽象ベースクラスの使用が必要である:1、抽象ベースクラスを直接継承するサブクラスを直接継承する柔軟性はありません.抽象ベースクラスでは「抽象メソッド」と「抽象属性」を宣言できます.抽象ベースクラスの「抽象」の内容を完全に上書き(実装)してからインスタンス化されますが、仮想サブクラスはその影響を受けません.2、仮想サブクラスは他のクラスを「抽象ベースクラスに登録」し、仮想サブクラスの下で仮想サブクラスとして登録します(registerメソッドを呼び出す)仮想サブクラスの利点は、あなたが実装したサードパーティのサブクラスがベースクラスから直接継承する必要がなく、抽象ベースクラスの一部のAPIインタフェースを実装したり、実装したりする必要がないことですが、issubclass()、issubinstance()が判断したときも真の値を返します.
pythonでは抽象クラスと抽象メソッドは提供されていませんが、抽象クラスの実装をシミュレートするために内蔵モジュールabc(abstract base class)が提供されています.
例:抽象ベースクラスを定義する簡単な方法:まずDogでDuckはAnimalから継承されます.Animalではeatとrunの2つのメソッドが定義されており、Animalから継承されたサブクラスはeatとvoiceメソッドを実装する必要があります.呼び出し時にエラーが発生します
例:
class Animal(object):
    def eat(self):
        raise NotImplementedError

    def run(self):
        raise NotImplementedError

class Dog(Animal):
    def eat(self):
        print("dog is eating")

    def run(self):
        print("dog is running")


class Duck(Animal):
    def eat(self):
        print("duck is eating")

    # def run(self):
    #     print("duck is running")


dog = Dog()
duck = Duck()
dog.eat()
dog.run()
duck.eat()
duck.run()

#   
dog is eating
dog is running
duck is eating
Traceback (most recent call last):
  File "D:/py3.7Project/sample/chapter01/all_is_object.py", line 83, in 
    duck.run()
  File "D:/py3.7Project/sample/chapter01/all_is_object.py", line 59, in run
    raise NotImplementedError
NotImplementedError

以上の皆さんは実装方法を学び始めました.この実装は呼び出し方法の時に間違いを報告します.実際の状況では不合理な点があります.duckインスタンス化に成功した後、eat、runの行為を持つべきです.アヒルは生まれてから食べることができ、走ることができるはずです.だから、eatやrunの方法を実現しなければ、インスタンス化は失敗するはずです.
修正コードは次のとおりです.
import abc
class Animal(metaclass=abc.ABCMeta):
    @abc.abstractmethod
    def eat(self):
        pass

    @abc.abstractmethod
    def run(self):
        pass

class Dog(Animal):
    def eat(self):
        print("dog is eating")

    def run(self):
        print("dog is running")


class Duck(Animal):
    def eat(self):
        print("duck is eating")

    # def run(self):
    #     print("duck is running")


dog = Dog()
duck = Duck()
dog.eat()
dog.run()
duck.eat()


#   
Traceback (most recent call last):
  File "D:/py3.7Project/sample/chapter01/all_is_object.py", line 80, in 
    duck = Duck()
TypeError: Can't instantiate abstract class Duck with abstract methods run

結果はインスタンス化できず、eatメソッドが実装されていないことを示す.抽象ベースクラスを実現しないすべての方法はインスタンス化できないという目的を達成した.