2017-05-05 15 views
-1

私はこの継承したクラスから基本クラスのコンストラクタを呼び出すことが多いこのユースケースを理解しようとしていますが、これを行う唯一の目的は、初期化されていますか?それとも、他の可能性のあるユースケースがありますか?それはちょうど、基本クラスが初期化されていることを確実にするためであることの唯一の目的は、なぜ継承されたクラスから基本クラスのコンストラクタを呼び出すのですか

class Base: 
    def __init__(self): 
     print('Base.__init__') 


class A(Base): 
    def __init__(self): 
     super().__init__() 
     print('A.__init__') 

答えて

2

のですか?

いいえ、どういう意味ですか、ちょうど

基本クラスに存在する理由があると仮定すると、となる必要があります。

それは@staticmethod機能のちょうど便利なコレクションの場合を除き、それがないものは何でもその__init__そのクラスのオブジェクトがどのように動作するかだから、と呼ばれたに依存する場合があります。

基本クラスに空の__init__がある場合でも、今後の変更がある場合は、それを呼び出すのが賢明です。

また、他にも利用可能なケースがありますか?

ユースケースは、オブジェクトの基本クラス部分が正しく初期化されていることを確認することです。それがなければ、の非スタティックメソッドのを安全に呼び出すことはできません。

原則として、基底クラスは、__init__(背景スレッドを開始するか、インスタンスをいくつかのシングルトンで登録するなど)で何かをする可能性があります。だから、インスタンス変数を代入する以外の効果があるかもしれませんが、これはまだその基本クラスのオブジェクトを初期化することの一部です。

+0

あなたの答えのおかげで、私は私は本当に子供クラスから基底クラスのメソッドを呼び出すの概念を理解することができた使用して実用的なユースケースのために、より探していた、私は私が実際に活用されていない経験を欠いています推測私のコード設計における継承の完全な力。 –

0

C++またはJavaの場合、コンパイラーは、(引数のない呼び出しを自動的に挿入するか、エラーを出すことによって)基本クラスのコンストラクターを呼び出す必要があります。

Pythonはas it is written、それを自分で呼び出すことが必要です。

基底クラスが__init__()メソッド、派生クラスの__init__()メソッドを持っている場合は、いずれかの場合には、明示的に基底クラスの適切な初期化を確実にするために、それを呼び出す必要がありますインスタンスの一部

なぜオブジェクト指向設計の原則なのですか? 「A」は「Base」であり、A「has-a」と同じ意味で書かれてもよい。BaseBaseの実装に特に干渉しない限り、オブジェクトを設計どおりに初期化する必要があります。コンストラクタをスキップすると、Baseオブジェクトは不適切に初期化され、Baseオブジェクトとして動作すると期待している人は失望します。

コンストラクタ以外のメソッドをオーバーライドする場合、基本クラスの実装に委譲するか、それを完全にオーバーライドすることはプログラマの裁量です。これは依然として不正な動作につながります---いくつかのAPIドキュメント "このメソッドをオーバーライドすると、さまざまなメソッドのためにsuperを呼び出す必要があります"というドキュメントを後で思いつくことができます。

+0

C++では、少なくとも省略された場合、ベースクラスのデフォルトコンストラクタが暗黙的に呼び出されます。引数を取る場合は、明示的に呼び出す必要があります。 – Useless

0

これは、基本クラスが通常初期化するすべてのものを初期化することです。たとえば、

class Base: 
    def __init__(self, number): 
     print('Base.__init__') 
     self.number = number 


class A(Base): 
    def __init__(self, number, string): 
     super().__init__(number) 
     self.string = string 
     print('A.__init__') 

このコード例では、より明白です。 Aが基本コンストラクタを呼び出すと、基本コンストラクタはself.numberのような必要なものをすべて初期化します。このようにして、Aの初期化関数の残りの部分は、再初期化せずに基本初期化関数の上に構築できます。この例では、ABaseの上に構築され、self.stringself.numberの上に追加しています。

関連する問題