为什么这个多态性不能用于python

时间:2015-04-10 14:36:10

标签: python oop polymorphism

让我们考虑以下计划:

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)

嗯,我对多态性的调整不是很好,但我不太明白为什么这不起作用.Python似乎要求Player类给出的8个参数但不是说明对象中的参数。

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

编辑:对不起,我是完全白痴......我说的是由于我对继承的理解不足而导致了一些明显的错误,或者是否无法将自己的参数添加到继承的函数中?

3 个答案:

答案 0 :(得分:3)

当您在子类中重新定义方法时,它完全替换原始。您仍然可以在父类中调用该版本,但在找到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来获取一个代理对象,该对象允许您访问在父类上定义的方法,但您也可以直接检索未绑定的方法:

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.

但是您需要再次显式地命名该基类,并将self显式传递给该方法。

答案 1 :(得分:2)

您的代码不是您实际运行的代码,但问题很明确:您希望派生对象的__init__函数在某种程度上应该是两个__init__函数的组合,但这不是它的工作原理。孩子的__init__是唯一一个为孩子打电话的人。如果要为超类提供参数,派生类必须接受它们并将它们传递给Object.__init__(它必须显式调用)。

此行为称为method overriding。 Python在method overloading的java或C ++意义上没有多态性:如果尝试仅使用两个参数初始化Player对象,则不会触发对Object.__init__()的调用;您仍然在调用Player.__init__(),并收到错误消息。

答案 2 :(得分:1)

  • 首先,您需要使用新的Python类,即父类应该从object继承。
  • 然后您需要接受子类中的父类参数。一种简单的方法是通过*args**kwargs特殊参数。
  • 最后,您需要调用父类__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)