为什么这种多态性不起作用 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)
让我们考虑以下程序:
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)