2014-01-06 47 views
5

我想了解課程是如何工作的。我想有一些共同的元素和其他人不能創造不同的類,但據我所知,我可以從三種不同方式創建:創建課程遵循哪種策略?

  • 與所有共享元素創建一個類,然後繼承這個類並修改新類中的具體方法和屬性。類似的東西:

    class Enemy(object): 
        """Enemy!""" 
        def __init__(self, damage=30, life=100, enemy="Hero"): 
        #And keep defining the class and its methods and attributes in common with all the enemys 
    
    class Troll(Enemy): 
        """Troll!""" 
        def __init__ (self, defense=0): 
        #And define the specific attributes and methods for Trolls. 
    
  • 創建一個類,並要求類型的類,並改變從輸入它得到了對象的定義。類似的東西:

    class Enemy(object): 
        """Enemy!""" 
        def __init__(self, damage=30, defense=0, life=100, type="Troll" enemy="Hero"): 
         if type=="Troll": 
          #Do that for type "Troll" 
         if type=="Goblin": 
          #Do that for type "Goblin" 
         #And keep defining the class and its methods and attributes for each accepted type 
    
  • 創建兩個不同的類,然後做多重繼承:

    class Enemy(object): 
        """Enemy!""" 
        def __init__(self, damage=30, life=100, enemy="Hero"): 
         #And keep defining the class and its methods and attributes in common with all the enemys 
    
    class Trolls(object): 
        """Trolls!""" 
        def __init__ (self, defense=1, shield=20): 
         #And define the specific attributes and methods for Trolls. 
    
    class SuperTroll(Enemy, Trolls): 
    

我看到的第一個是最簡單的一個,讓我可以更靈活地創建多個具有共享方法和屬性的類。但第二個在我看來更容易使用(或者至少我喜歡它),並且無論我想要什麼條件,我都可以跳出if條件。第三種方法對於混合不同的類沒有任何共享的方法或屬性是可行的,如果它們共享它不會弄亂它(或者它會?)。

哪一個更好?
但是關於以某種方式編寫代碼似乎只是一個關於如何實現代碼的策略問題。 這是正確的嗎?

+0

第二個不是面向對象的。當你想添加新的敵人類型時,你會做什麼?你希望能夠在不改變基類的情況下創建一個新的 – Elisha

+0

我很困惑你的第三種方法。爲什麼要有「Trolls」類和「Troll」類?有什麼不同? – Kevin

+3

我正要推薦對抗第三名,但意識到它有一個有用的區別:「敵人」是一個角色,可以應用於各種種族。 「巨魔」是一個種族,但可能會有「朋友」巨魔和「敵人」巨魔。也就是說,這意味着一個更爲豐富的階級體系似乎是必要的,所以我會推薦第一種方法。 – chepner

回答

2

第二個例子不是一個好主意;它會導致很多重複的代碼,並且每當你想出一個新類型的敵人角色時,你必須編輯你的Enemy類。

第一個和第三個之間的挑剔是棘手的,取決於你想達到的目標(「戰略問題」,就像你擁有它)。

Enemy第一,單繼承了TrollGoblin,是有用的,因爲它允許您定義所有的所有Enemy人物角色將有一次,並且只定義在TrollGoblin階級差異的代碼。你可以進一步擴展它,並且從一個超類(或元類)Character繼承,它提供了EnemyHero類(例如name,health,...)的真正基本的東西。

class Enemy(Character) 

class Troll(Enemy) 

如果您想要分隔字符和角色,例如,你可以有

class FriendlyTroll(Troll, Friend) 

class UnfriendlyTroll(Troll, Enemy) 

如果這些角色都將意味着不同的實例屬性(例如在Friend混入物可能會引入share方法)。這可以讓你的角色定義更加複雜,但是如果你不打算使用額外的功能,那麼讓你的頭腦變得複雜很多,並且可能導致棘手的多重繼承問題。

TL; DR:使用第一個!如果您後來決定確實需要將角色分離爲混合類,那麼這不是一個複雜的任務。

+0

他們在評論中指出,反對第二種情況的好處。並感謝您解釋哪種策略更適合在哪些情況下遵循。 – Llopis

2
First one: 

正確的路要走......你是從什麼是共同的「敵人」繼承。在這裏,你可以在課堂中擁有「ENEMY」共同的東西,併爲所有類型的敵人提供單獨的課程,而且你可以很好地重寫某些使某種「ENEMY」截然不同的方法。

Second one: 

不是很好或正確面向對象的原因是什麼,如果「巨魔」有沒有被其他的「敵人」共享某些屬性。你可能會說它可以放在你的「if」語句下,但是這會使得代碼非常容易管理,這就是爲什麼你使用OOP(管理代碼,它不是全部,而是其中一個原因)。

Third one: 

我強烈建議儘可能不要使用多重繼承。谷歌鑽石死亡問題,你會知道爲什麼。多重繼承的一個規則 - 「如果你認爲你需要多重繼承,那麼你可能是錯的,如果你知道你必須使用多重繼承,那麼你可能是對的。」

+0

python中沒有真正的鑽石問題。 http://python-history.blogspot.ca/2010/06/method-resolution-order.html –

+0

我試圖暗示多重繼承應該是最後一種選擇。 –

+0

謝謝,我會避免第二個,然後嘗試避免第三個。 – Llopis

1

好吧,類本質上描述了這些類的對象的行爲的差異。那就是你可以選擇任何一種方法,但只有在你坐下後決定:

你的程序給定的巨魔和敵人之間的區別是什麼。如果存在這樣的差異(即有些情況下,「巨魔」的行爲與一般敵人有所不同,或者有自己的方法(行動)等),那麼你需要區分等級巨魔和等級敵人。如果他們不同的是他們的名字,那麼你可能不需要一個單獨的類...

只有當你需要混合兩個不相關的類的行爲時,你需要多重繼承(第三種情況)。一般來說,這是一個艱難的路,有一些陷阱和陷阱。但是,如果你足夠聰明,準確,那麼你可以成功。

+0

目前我將避免多繼承,因爲我還沒有學過繼承。謝謝您的幫助。 – Llopis