2017-09-08 2 views
0

を継承し、私は次のような問題Pythonのクラスのコールスーパーのメソッドの代わりに、

class A: 
    def __init__(self): 
     self.window = "<I am window class>" 

class B(A): 
    def __init__(self): 
     super().__init__() 

    def createObject(self): 
     print(self.window) # it works here 
     self.c = C() 

    def drawRect(self): 
     print(self.window) # does not work when called from class C 

class C(B): 
    def __init__(self): 
     self.draw() 

    def draw(self): 
     super().drawRect() 

app = B() 
app.createObject() 

を持っている私は、私はクラスC にsuper().drawRect()関数を呼び出すとき、それは自己として<__main__.C object at 0x0000023D99FA6748>を送ること考え出しています。

どのように私は(関数drawで、クラスCを作ることができるが)私はBクラス自体からの関数を呼び出す際に非簡略化されたコードでは、それは自己を表示しますので、私は求めていますsuper().drawRect()

<__main__.B object at 0x0000017A2BA95358>を送信します.windowですが、Cクラスから呼び出されたときには何も出力されません。

どのように修正できますか? 私は何が間違っていますか?あなたがCのインスタンスを作成するときに

答えて

1

Bを継承するために起こるだけCインスタンスがある、ないBオブジェクトはありません。

だからあなたの質問への答え:

私は機能draw()で、クラスCを作ることができる方法がsuper().drawRect()

<__main__.B object at 0x0000017A2BA95358>を送信です:あなたがすることはできません。

Cオブジェクトの横に新しいBオブジェクトを作成できます(ただし、継承の目的に反する)。

しかし、あなただけC.__init__super().__init__を呼び出す必要があることをより合理的なようだ:

class C(B): 
    def __init__(self): 
     super().__init__() 
     self.draw() 

    def draw(self): 
     super().drawRect() 

とにかくことをしない奇妙なことでしょう。継承の種類は、より完全にではなく、であることを意味します。

しかし、あなたはおそらく代わりに相続する別の方法(例えばcomposition)を把握する必要があり、あなたのB.createObject方法とBからC継承にself.c = C()を行うことを考えれ:しかし、これは基準サイクルを作成します

class A: 
    def __init__(self): 
     self.window = "<I am window class>" 

class B(A): 
    def __init__(self): 
     super().__init__() 

    def createObject(self): 
     print(self.window) # it works here 
     self.c = C(self) 

    def drawRect(self): 
     print(self.window) # does not work when called from class C 

class C(object): # don't inherit from B 
    def __init__(self, obj): 
     self.obj = obj 
     self.draw() 

    def draw(self): 
     self.obj.drawRect() 

app = B() 
app.createObject() 

をインスタンスをBインスタンスの属性として格納し、BインスタンスをCインスタンスの属性として格納するためです。また、コードをあまりにも単純化した可能性もあります。実際のコードは、何らかの形で合成を妨げる可能性があります。しかし、Bから継承しているようなコードでは、Bの動作を完全に上書きし、そのメソッドの属性を使用しない(クラスをオーバーライドすることができないため)ことができない場合、クラスCの悪い考えです。あなたは、クラスCのコンストラクタに

super().__init__() 

を呼び出す必要が

関連する問題