【问题标题】:Why does this polymorphism not work python为什么这种多态性不起作用python
【发布时间】:2015-04-10 14:36:10
【问题描述】:

让我们考虑以下程序:

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 个参数,但不考虑 Object 中的参数.

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

编辑:对不起,我是个彻头彻尾的白痴……我的意思是,由于我对继承缺乏了解,或者无法将自己的参数添加到继承的函数中,我是否犯了一些明显的错误?

【问题讨论】:

  • 搞错这里的PERSON 是什么?
  • 那是我的错误...我的意思是 PLAYER。
  • PLAYER 也没有在任何地方定义。请发布 实际 代码并解释您正在尝试做什么,因为这个问题现在不是很明显
  • @user2592835:那么这里的PLAYER 是什么?你只有Player; Python 区分大小写。
  • 你是不是故意不调用超类的构造函数?

标签: python oop polymorphism


【解决方案1】:

当您在子类中重新定义方法时,它会完全替换原来的方法。您仍然可以在父类中调用该版本,但在寻址 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 显式传递给该方法。

【讨论】:

    【解决方案2】:

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

    这种行为称为method overriding。 Python 没有 method overloading 的 java 或 C++ 意义上的多态性:如果您尝试仅使用两个参数初始化 Player 对象,您将不会触发对 Object.__init__() 的调用;你仍然会打电话给Player.__init__(),并得到一个错误。

    【讨论】:

      【解决方案3】:
      • 首先,您需要使用新的 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)
      

      【讨论】:

      • 当我将此解决方案添加到我的代码时,我收到错误“必须键入而不是 classobj”...
      • 您是否继承自 objectObject 类?
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-10-13
      • 2011-12-16
      • 2011-01-23
      • 2014-02-01
      相关资源
      最近更新 更多