2015-03-23 12 views

cevap

53

Sizin GameObjectPlayerveEnemy devralmakta. EnemyzatenPlayer Python öğesinden devraldığı için, ilk önce hangi yöntemin nasıl görüneceğini belirleyemiyor; Player veya Enemy adresinde Player'da tanımlanan şeyleri geçersiz kılar.

Tüm temel sınıfları Enemy burada adlandırmanız gerekmez; Sadece tek bir sınıftan miras:

class GameObject(Enemy): 
    pass 

Enemy zaten Player içerir

, yeniden dahil etmek gerekmez.

4

Ne yazdığınız, bir Player ve bir Enemy olması için bir GameObject istersiniz. Ancak bir Enemy zaten bir Player'dur. Eğer miras ilk Player itibaren a veya Enemy miras yoluyla size miras Player dan biri olmalıdır: MRO sorunu sadece belirsiz olacağını GameObject durumda bu alan için soran Player bir alan a olsaydı belirtiyor ?

Ama burada kalıtım yerine kompozisyon kullanmak istemediğinize emin misiniz?

class GameObject(object): 
    def __init__(self): 
     self.player = Player() 
     self.enemy = Enemy() 
9

Orijinal kodun çalışma nedenini açıklayacağım. Python, örnek özniteliği/yöntemine bakarken hangi temel sınıfta (doğrudan ve dolaylı) arama yapılacağına karar vermek için Python'un karar vermesi gerekir. Bu, miras grafiğini doğrusallaştırarak yapar, yani temel sınıfların grafiğini C3 or MRO adlı bir algoritma kullanarak bir diziye dönüştürür. MRO algoritması birkaç istenen özelliklerini elde benzersiz algoritma şudur: Her soy sınıfı tam olarak bir kez

  • bir sınıf her zaman atası ("monotonluk") önce görüntülenen görünür

    1. aynı sınıfın
    2. doğrudan ebeveynler gerektiği onlar sınıf tanımının ("tutarlı yerel öncelik sırası") sınıfının A çocukları hep sınıfın B çocukları önce görünür eğer
    3. ardından A görünmelidir listelenen aynı sırada görüntülenmeden önce B ("tutarlı uzatılmış öncelik sırası")

    Kodunuzda, ikinci kısıtlama önce Enemy önce görünür; Üçüncü kısıtlama, önce Player'un görüntülenmesini gerektirir. Tüm kısıtlamaları karşılamanın bir yolu olmadığından, python sizin miras hiyerarşinizin geçersiz olduğunu bildirir.

    class GameObject(Enemy, Player): 
        pass 
    

    Bu sadece teknik bir ayrıntı değil: Eğer şöyle GameObject baz sınıfların düzenini geçerseniz

    Kodunuz çalışacaktır. Bazı (umarım nadiren) durumlarda, yöntem birden çok sınıfta tanımlanmışsa, çağırdığınız yöntemi almak için hangi sınıfın kullanılması gerektiğini düşünmek isteyebilirsiniz. Temel sınıfları tanımladığınız sıra, bu seçimi etkiler.

  • +2

    Bu kabul edilenlerden çok daha iyi bir yanıttır. –

    İlgili konular