2016-07-09 82 views
0

我正在編寫一個遊戲的動態。遊戲中有兩種障礙,可以推動的塊和球。我希望球在被推動時開始滾動。如何讓子類擴展Python中超類的方法

所以我寫了下面的代碼:Barrier

class Barrier: 
    def __move(self): 
     print 'Moving' 

    def push(self): 
     if self.canMove(): 
      self.__move() 
     else: 
      pass # Push barriers in front of it 

    def canMove(self): 
     return True 

class Ball(Barrier): 
    def __move(self): 
     self.__startRolling() 
     super(Ball, self).__move() 

    def __startRolling(self): 
     print 'Started rolling' 

class Block(Barrier): 
    # bla bla bla 
    pass 

push()被調用時,類將檢查其是否可以移動(在前面其他貿易壁壘也可以防止其移動),然後調用self.__move()。對於類Ball,它將覆蓋此方法並在移動之前開始滾動。

有兩個問題。首先,當我跑下面的代碼:

ball = Ball() 
ball.push() 

我只是在屏幕上得到Moving,但沒有Started rolling

其次,當我跑:

ball = Ball() 
ball._Ball__move() 

我:

Traceback (most recent call last): 
    File "F:\project\test.py", line 25, in <module> 
    ball._Ball__move() 
    File "F:\project\test.py", line 15, in __move 
    super(Ball, self).__move() 
TypeError: must be type, not classobj 

如何能實現我的目標是什麼?

+0

我解決了第一個問題,在'Ball'類中將'def __move'改爲'def move'。但是我仍然不知道如何解決第二個問題,我必須以不同的方式命名'Barrier'類中的'move'函數(例如'_Barrier__move')來調用它。這樣,我還需要在'Block'類中實現'move'函數,但是我希望它只是繼承'Barrier'類中的'move'函數。 – LouYu

回答

1

您遇到的問題是由於__move()中的兩個前導下劃線造成的。這會導致名稱損壞。

在第一種情況下你的電話被分派到Barrier.__move()而不是Ball.__move()因爲外線接球類Ball.__move()僅作爲_Ball__move()這顯然不是從Barrier.push()調用。

在第二種情況下,我得到:

AttributeError: 'super' object has no attribute '_Ball__move' 

而這又是由於名稱截斷。 super()不會有_Ball__move()屬性。

要實現您的目標,您可以刪除兩個前導下劃線。

PEP-8:爲避免名稱與子類發生衝突,請使用兩個前導下劃線來調用Python的名稱修改規則。

+0

你有一個小錯字:'_Ball .__ move()'。那裏有額外的點。也許值得注意的是,如果OP希望阻止通過使用類的代碼直接調用方法,則它們可以使用單個下劃線。 – jpmc26