Object-oriented-python-inheritance-and-ploymorphism
継承とポリモーフィズム
継承とポリモーフィズム-これはPythonで非常に重要な概念です。 あなたが学びたいなら、あなたはそれをよりよく理解しなければなりません。
継承
オブジェクト指向プログラミングの主な利点の1つは再利用です。 継承は、同じことを達成するメカニズムの1つです。 継承により、プログラマーは最初に一般クラスまたは基本クラスを作成し、後でそれをより専門的なクラスに拡張できます。 プログラマーはより良いコードを書くことができます。
継承を使用すると、基本クラスで使用可能なすべてのデータフィールドとメソッドを使用または継承できます。 後で独自のメソッドとデータフィールドを追加できるため、継承はコードを最初から書き直すのではなく、コードを整理する方法を提供します。
クラスXがクラスYを拡張するオブジェクト指向の用語では、Yはスーパー/親/ベースクラスと呼ばれ、Xはサブクラス/子/派生クラスと呼ばれます。 ここで注意すべき点は、プライベートではないデータフィールドとメソッドのみが子クラスからアクセスできることです。 プライベートデータフィールドとメソッドは、クラス内でのみアクセス可能です。
派生クラスを作成する構文は-
class BaseClass:
Body of base class
class DerivedClass(BaseClass):
Body of derived class
属性を継承する
今、以下の例を見てください-
出力
最初にDateというクラスを作成し、オブジェクトを引数として渡します。here-objectはPythonが提供する組み込みクラスです。 その後、timeという別のクラスを作成し、Dateクラスを引数として呼び出しました。 この呼び出しを通じて、Dateクラスのすべてのデータと属性にアクセスし、Timeクラスにアクセスします。 そのため、以前に作成したTimeクラスオブジェクトtmからget_dateメソッドを取得しようとしています。
Object.Attribute Lookup Hierarchy
- インスタンス
- クラス
- このクラスが継承するすべてのクラス
継承の例
継承の例を見てみましょう-
いくつかのクラスを作成して、例に参加しましょう-
- Animal-クラスは動物をシミュレートします
- 猫-動物のサブクラス
- 犬-動物のサブクラス
Pythonでは、オブジェクト(インスタンス)を作成し、属性の値を割り当てるために使用されるクラスのコンストラクター。
サブクラスのコンストラクターは常に親クラスのコンストラクターに呼び出され、親クラスの属性の値を初期化してから、属性の値の割り当てを開始します。
出力
上記の例では、すべてのサブクラスまたは子クラスが親クラスからそのプロパティを継承するように、親クラスに配置したコマンド属性またはメソッドが表示されます。
サブクラスが別のサブクラスからメソッドまたはデータを継承しようとすると、Dogクラスがそのcatクラスからswatstring()メソッドを呼び出そうとすると、エラーが発生します(この場合はAttributeErrorなど)。
ポリモーフィズム(「多くの形状」)
ポリモーフィズムはPythonのクラス定義の重要な機能であり、クラスまたはサブクラス全体で一般的に名前の付いたメソッドがある場合に利用されます。 これにより、関数は異なるタイプのエンティティを異なる時間に使用できます。 そのため、柔軟性と疎結合を提供するため、コードを拡張し、長期間にわたって簡単に維持できます。
これにより、クラス全体の違いを意識する必要なく、関数はこれらの多態性クラスのオブジェクトを使用できます。
ポリモーフィズムは、サブクラスが基本クラスのメソッドを使用するかオーバーライドすることにより、継承を通じて実行できます。
私たちの以前の継承の例でポリモーフィズムの概念を理解し、両方のサブクラスでshow_affectionと呼ばれる1つの一般的なメソッドを追加しましょう-
私たちが見ることができる例から、それは異なるタイプのオブジェクトが同じ方法で、またはより具体的には同じメソッドまたは同じメソッド(以下の例のshow_affection)いずれかのタイプのオブジェクトで呼び出されます。
出力
そのため、すべての動物は愛情(show_affection)を示しますが、それらは異なっています。 したがって、「show_affection」ビヘイビアは、動物によって異なる動作をするという意味で多形的です。 したがって、抽象的な「動物」の概念は実際には「show_affection」ではありませんが、特定の動物(犬や猫など)にはアクション「show_affection」の具体的な実装があります。
Python自体には、ポリモーフィックなクラスがあります。 たとえば、len()関数は複数のオブジェクトで使用でき、すべてが入力パラメーターに基づいて正しい出力を返します。
オーバーライド
Pythonでは、サブクラスにスーパークラスのメソッドをオーバーライドするメソッドが含まれている場合、次を呼び出すことでスーパークラスメソッドを呼び出すこともできます。
self.methodの代わりにSuper(Subclass、self).method。
例
class Thought(object):
def __init__(self):
pass
def message(self):
print("Thought, always come and go")
class Advice(Thought):
def __init__(self):
super(Advice, self).__init__()
def message(self):
print('Warning: Risk is always involved when you are dealing with market!')
コンストラクターの継承
前の継承の例からわかるように、initはupの親クラスにあり、「子クラスdogまたはcatはinitメソッドを持っていなかったためです」 Pythonは、継承属性ルックアップを使用して、動物クラスでinitを見つけました。 子クラスを作成すると、最初にdogクラスのinitメソッドが検索されますが、それが見つからなかった後、親クラスAnimalが検索され、そこで検索されて呼び出されました。 クラスの設計が複雑になったため、最初に親クラスコンストラクターで処理し、次に子クラスコンストラクターで処理するインスタンスを初期化することができます。
出力
上記の例では、すべての動物には名前があり、すべての犬には特定の品種があります。 superで親クラスコンストラクターを呼び出しました。 したがって、dogには独自のinitがありますが、最初に起こるのはsuperと呼ぶことです。 スーパーは組み込み関数であり、クラスをそのスーパークラスまたはその親クラスに関連付けるように設計されています。
この場合、犬のスーパークラスを取得し、犬のインスタンスをここで言うコンストラクタinitのメソッドに渡すと言います。 つまり、別の言い方をすると、dogオブジェクトを使用して親クラスAnimal initを呼び出しています。 犬のインスタンスでどうしてAnimal initと言わないのか、と尋ねることができますが、これを行うことはできますが、動物のクラスの名前が変更される場合は、将来的になります。 クラス階層を再配置したい場合、犬は別のクラスから継承します。 この場合にsuperを使用すると、物事をモジュール式に保ち、変更と保守を簡単に行うことができます。
したがって、この例では、一般的なinit機能をより具体的な機能と組み合わせることができます。 これにより、コードの重複を排除し、システム全体の設計を反映するようにクラスを相互に関連付けることができる特定の機能から共通の機能を分離することができます。
結論
- initは他のメソッドと同様です。継承できる
- クラスにinitコンストラクターがない場合、Pythonは親クラスをチェックして、クラスを見つけることができるかどうかを確認します。
- Pythonはそれを見つけるとすぐにそれを呼び出し、検索を停止します
- super()関数を使用して、親クラスのメソッドを呼び出すことができます。
- 独自のクラスと同様に親で初期化することもできます。
多重継承とルックアップツリー
名前が示すように、多重継承はPythonがクラスが複数のクラスから継承する場合です。
たとえば、子は両方の親(母と父)から性格特性を継承します。
Python多重継承構文
クラスが複数の親クラスを継承するように、これらのクラスの名前をかっこ内に派生クラスに定義し、それを定義します。 これらの名前はコンマで区切ります。
以下はその例です-
>>> class Mother:
pass
>>> class Father:
pass
>>> class Child(Mother, Father):
pass
>>> issubclass(Child, Mother) and issubclass(Child, Father)
True
多重継承とは、2つまたは3つ以上のクラスから継承する機能のことです。 子は親から継承し、親は祖父母クラスから継承するため、複雑さが生じます。 Pythonは、オブジェクトからの読み取りが要求されている属性を検索する継承ツリーを登ります。 インスタンス内、クラス内、親クラス、最後に祖父母クラスからチェックします。 ここで、クラスが検索される順序(呼吸優先または深さ優先)で問題が発生します。 デフォルトでは、Pythonは深さ優先になります。
それが、下の図でPythonがクラスAで最初にdothis()メソッドを検索する理由です。 したがって、以下の例のメソッド解決順序は次のようになります
*Mro-D→B→A→C*
以下の多重継承図を見てください-
Pythonの「mro」機能を理解するための例を見てみましょう。
出力
実施例3
「ダイヤモンド形状」多重継承の別の例を見てみましょう。
Diamond Shape Multiple Inheritance
上記の図は曖昧と見なされます。 「メソッド解決順序」を理解する前の例から。 mroはD→B→A→C→Aになりますが、そうではありません。 Cから2番目のAを取得すると、Pythonは前のAを無視します。 この場合、mroはD→B→C→Aになります。
上記の図に基づいて例を作成しましょう-
出力
上記の出力を理解するための簡単なルールは、同じクラスがメソッド解決順序に現れる場合、このクラスの以前の外観はメソッド解決順序から削除されます。
結論として-
- どのクラスも複数のクラスから継承できます
- Pythonは通常、継承クラスを検索するときに「深さ優先」の順序を使用します。
- しかし、2つのクラスが同じクラスを継承する場合、Pythonはmroからそのクラスの最初の外観を削除します。
デコレータ、静的およびクラスメソッド
関数(またはメソッド)はdefステートメントによって作成されます。
メソッドは、メソッドの最初の引数がインスタンスオブジェクトである1点を除いて、関数とまったく同じように機能しますが。
次のように、振る舞いに基づいてメソッドを分類できます。
- シンプルメソッド-クラスの外部で定義されています。 この関数は、インスタンス引数を渡すことでクラス属性にアクセスできます。
def outside_func(():
- インスタンスメソッド-
def func(self,)
- クラスメソッド-クラス属性を使用する必要がある場合
@classmethod
def cfunc(cls,)
- 静的メソッド-クラスに関する情報がありません
@staticmethod
def sfoo()
これまでインスタンスメソッドを見てきましたが、今が他の2つのメソッドについての洞察を得るときです。
クラスメソッド
@classmethodデコレータは、呼び出されたクラスまたは最初の引数として呼び出されたインスタンスのクラスを渡す組み込み関数デコレータです。 その評価の結果は、関数定義を隠します。
構文
class C(object):
@classmethod
def fun(cls, arg1, arg2, ...):
....
fun: function that needs to be converted into a class method
returns: a class method for function
彼らはこのcls引数にアクセスできます。オブジェクトインスタンスの状態を変更することはできません。 それは自己へのアクセスを必要とするでしょう。
- クラスのオブジェクトではなく、クラスにバインドされます。
- クラスメソッドは、クラスのすべてのインスタンスに適用されるクラス状態を引き続き変更できます。
静的メソッド
静的メソッドはselfもcls(class)パラメーターも受け取りませんが、任意の数の他のパラメーターを自由に受け入れることができます。
構文
class C(object):
@staticmethod
def fun(arg1, arg2, ...):
...
returns: a static method for function funself.
- 静的メソッドは、オブジェクトの状態もクラスの状態も変更できません。
- アクセスできるデータが制限されています。
何を使用するか
- 通常、クラスメソッドを使用してファクトリメソッドを作成します。 ファクトリメソッドは、さまざまなユースケースのクラスオブジェクト(コンストラクタに類似)を返します。
- 通常、静的メソッドを使用してユーティリティ関数を作成します。