2

メソッド/プロパティの共通セットを同じクラスから派生したサブクラスに追加する適切な方法は何ですか?

これらは、動物に基づくビデオゲームに必要な私のクラスであるとしましょう (これは単なる例です。実際にゲームを書いているわけではありませんが、考え方は同じです)。

class Animal():
    def __init(self, numlegs):
        self.numlegs = numlegs

class Dog(Animal):
    def __init(self, numlegs):
        Animal.__init__(self, numlegs)

    def bark(self):
        print "Arf!"

class Cat(Animal):
    def __init(self, numlegs):
        Animal.__init__(self, numlegs)

    def playwithmouse(self):
        print "It's fun!"

class Duck(Animal):
    def __init(self, numlegs):
        Animal.__init__(self, numlegs)

    def fly(self):
        print "Weee!"

ゲームの特定の時点で、Dog と Duck を武器化することができます。これらには同じメソッド (fire()、reload()) およびプロパティ (ammocount) が必要です。

ゲームのまったく別の部分で必要になるため、Animal() クラスに追加するのは正しくないと思います。

それらを追加する正しいアプローチは何でしょうか?

更新 予想される結果は、ある種の動物であることを追加したかった-武器ハイブリッドクラスのような

class BurtalDuck(Duck):
    fire(): #<- this is somehow added to Duck
        print "ratatatatat!"

私が答えから得たのは、「武器/弾薬」のセット全体が必要な場合はマルチクラスを使用できるということです。

4

4 に答える 4

4

次のように、Python で多重継承を利用できます。

class Weapon():
    def __init__(self):
        self.ammoCount = 0
    def fire():
        print "fire!"
    def reload():
        print "reloading!"

class Dog(Animal, Weapon):
    def __init(self, numlegs):
        Animal.__init__(numlegs)

    def bark(self):
        print "Arf!"

今、あなたはこれを行うことができます:

dog = Dog(4)
dog.fire()

ただし、Dogのみあり、ハイブリッドではない場合は、のインスタンスを使用して、それをコンポーネントとして犬に割り当てます。AnimalAnimalWeaponWeapon

class Dog(Animal, Weapon):
    def __init(self, numlegs):
        Animal.__init__(numlegs)
        self.weapon = Weapon()

    def bark(self):
        print "Arf!"

その場合は使用する必要がありますdog.weapon.fire()Dogこれは実際武器であるというあなたの概念に合わないかもしれませんが、今では武器化されています。:)

犬のインスタンスがあり、その場で武器化する必要がある場合は、Python の動的属性割り当てを利用してください。

class Dog(Animal):
    def __init(self, numlegs):
        Animal.__init__(numlegs)

    def bark(self):
        print "Arf!"
#some other code maybe
dog = Dog(4)
#more other code
dog.weapon = Weapon()
#even more code
dog.weapon.fire()

一般的に私は言うだろう:

  • 武器にしたいDog、または武器したい場合は、継承を使用してください。Duck
  • 1 つ (または複数) の武器が必要なDog場合Duck構成する場合、または持つ場合は、コンポーネントを使用します。
于 2012-06-18T16:07:02.410 に答える
3

これをコンポジションで行い、

class Weapon(object):
    def __init__(self, type):
        self.type = type

class Dog(Animal):
    def __init(self, numlegs):
        Animal.__init__(numlegs)
        self.gun = Weapon("gun")

    def bark(self):
        print "Arf!"
于 2012-06-18T16:15:53.377 に答える
2

1 つの可能性: それらをクラスにまったく追加しないでください。武器がどのように機能するかに関するすべての情報を含む「武器」クラスを作成し、そのクラスのインスタンスを武器にすることができるオブジェクトに追加します。

もちろん、これはアーキテクチャを少し再考することを意味しますが、考えるのに良い概念です。このアイデアは通常、「コンポーネントベース」という名前で呼ばれます。「コンポーネントベースのゲーム オブジェクト」を Google で検索し、アイデアを説明するブログ投稿やプレゼンテーションを見つけてみてください。

于 2012-06-18T16:13:38.770 に答える
0

ミックスインを使用した別のアプローチ:

class Animal(object):
    def __init__(self, n):
        super(Animal,self).__init__()
        if isinstance(n, Animal):  # copy constructor
            self.numlegs = n.numlegs
        else:
            self.numlegs = n
    def do(self):
        pass

class Dog(Animal):
    def do(self):
        print "Arf!"

class Cat(Animal):
    def do(self):
        print "Torturing small animals is fun!"

class Duck(Animal):
    def do(self):
        print "Wheee!"

class Weapon(object):
    def __init__(self):
        super(Weapon,self).__init__()
        self.ammocount = 7

    def fire(self):
        if self.ammocount > 0:
            print "Bang!"
            self.ammocount -= 1
        else:
            print "<click>"

    def reload(self):
        self.ammocount = 7

class WeaponizedDog(Dog, Weapon): pass
class WeaponizedCat(Cat, Weapon): pass
class WeaponizedDuck(Duck, Weapon): pass

max = Dog(4)                # max is a 4-legged dog
max.do()                    # "Arf!"
max = WeaponizedDog(max)    # If I put my hands in my pockets, I'd be carrying concealed deadly weapons...
max.fire()                  # "Bang!"
于 2012-06-18T18:03:57.163 に答える