为什么这种多态性不起作用 python

Why does this polymorphism not work python

让我们考虑以下程序:

class Object:
    def __init__(self,name,shortDesc):
        self.name=name
        self.shortDesc=shortDesc

class Player(Object):
    def __init__(self,health,armor,room,inventory,wearing,gender,money):
        self.health=health
        self.armor=armor
        self.room=room
        self.inventory=inventory
        self.wearing=wearing
        self.gender=gender
        self.money=money

player=Player("Will","Amazing",100,0,"start",[],[],"Male",0)

好吧,我不太适应多态性,但我真的不明白为什么这 work.Python 似乎不要求玩家 class 给出的 8 个参数,但是不考虑对象中的参数。

有可能我正在尝试做的事情是不可能的,如果是这样,请纠正我如何实现类似的目标...

编辑:对不起,我是个彻头彻尾的白痴...我想说的是,我是不是因为对继承缺乏了解而犯了一些明显的错误,或者是不可能将自己的参数添加到继承的函数中?

您的代码不是您实际的代码 运行,但问题很明确:您期望派生的 object 的 __init__ 函数应该以某种方式组合两个 __init__ 函数,但这不是它的工作原理。 child 的 __init__ 是唯一一个为 child 调用的。如果您想为 superclass 提供参数,派生的 class 必须接受它们并将它们传递给 Object.__init__(它必须显式调用)。

此行为称为 method overriding. Python doesn't have polymorphism in the java or C++ sense of method overloading:如果您尝试仅使用两个参数初始化 Player object,您将不会触发对 Object.__init__() 的调用;你仍然会调用 Player.__init__(),并得到一个错误。

当您在子class 中重新定义一个方法时,它完全替换了原来的方法。您仍然可以在父 class 中调用该版本,但是在寻址 Player.__init__ 时会找到您的 版本。

因此,Python 不会将您的参数拆分到 Player.__init__Object.__init__ 方法;你必须自己明确地这样做。让 Player.__init__ 接受 Object.__init__ 以及 的所有参数,然后将它们传递到链中:

class Player(Object):
    def __init__(self, name, description, 
                 health, armor, room, inventory, wearing, gender, money):
        super(Player, self).__init__(name, description)
        # rest of your Player initialisation.

我在这里使用 super() function 来获取一个代理对象,让您可以访问父 classes 上定义的方法,但您也可以直接检索未绑定的方法:

class Player(Object):
    def __init__(self, name, description, 
                 health, armor, room, inventory, wearing, gender, money):
        Object.__init__(self, name, description)
        # rest of your Player initialisation.

但随后您需要再次显式命名该基 class,并将 self 显式传递给该方法。

  • 首先,你需要使用新的Python classes,即父class应该继承自object
  • 那么您需要在子 class 中接受父 class 参数。一种简单的方法是通过 *args**kwargs 特殊参数。
  • 最后,您需要调用父class __init__方法并使用命名参数调用构造函数。

class Object(object):
    def __init__(self,name,shortDesc, *args, **kwargs):
        self.name=name
        self.shortDesc=shortDesc

class Player(Object):
    def __init__(self,health,armor,room,inventory,wearing,gender,
                 money, *args, **kwargs):
        super(Player, self).__init__(*args, **kwargs)
        self.health=health
        self.armor=armor
        self.room=room
        self.inventory=inventory
        self.wearing=wearing
        self.gender=gender
        self.money=money

player=Player(name="Will",shortDesc="Amazing",health=100,armor=0,
              room="start",inventory=[],wearing=[],gender="Male",money=0)