我试图了解继承如何在python中工作。我在看一个简单的代码,有一件事令我困惑。代码如下:
class Person:
def __init__(self, first, last):
self.firstname = first
self.lastname = last
def Name(self):
return self.firstname + " " + self.lastname
class Employee(Person):
def __init__(self, first, last, staffnum):
Person.__init__(self,first, last)
self.staffnumber = staffnum
def GetEmployee(self):
return self.Name() + ", " + self.staffnumber
x = Person("Marge", "Simpson")
y = Employee("Homer", "Simpson","1007")
print(x.Name())
print(y.GetEmployee())
我的问题是,当使用Person.__init__()
来调用baseclass的构造函数时,但是当我们再次调用基类的Name()方法时,而不是使用" Person",我们正在使用& #34;自&#34 ;.有人可以清除这种混乱,我理解继承如何在python中工作?
答案 0 :(得分:2)
Employee
类继承基础Person
类的方法,包括__init__
方法。因此,在类定义的顶部,它具有__init__
和Name
方法。
然后Employee
类定义将覆盖它继承的__init__
方法。要调用__init__
的{{1}}方法,必须按名称调用Person
(实际上,它可以使用Person.__init__
作为另一种选择)。
但由于super()
没有覆盖继承的Employee
方法,因此可以使用Name
来调用它在顶部继承的self.Name()
方法。< / p>
答案 1 :(得分:1)
以下两种方法是等效的(假设“Name”方法永远不会被覆盖):
class Employee(Person):
def __init__(self, first, last, staffnum):
Person.__init__(self, first, last)
self.staffnumber = staffnum
def getEmployee(self):
return Person.Name(self) + self.staffnumber
class Employee(Person):
def __init__(self, first, last, staffnum):
Person.__init__(self, first, last)
self.staffnumber = staffnum
def getEmployee(self):
return self.Name() + self.staffnumber
在第二个例子中,当调用self.Name()时,类的实例被“绑定”到函数中,因此不需要传递第一个参数。
因为在Employee子类中重写 init ,所以不能调用self。 init (first,last)。然后,您将调用Employee。 init (self,* args)而不是Person。 init (self,* args)。这将创建一个无限递归循环,否则你将得到一个参数错误。
作为一般规则,当您重写方法时,必须在子类中使用以下表示法。 ParentClass.methodname(self,* args,** kwargs)。您可以调用self.Name()的原因是因为名称尚未被覆盖。
我在这里重复一遍。这会使它结晶,还是让我更进一步困惑?
答案 2 :(得分:0)
简单的说法是self.method()
表示“调用method
可用的最具体的实现”(即,当前对象的继承树下最远的那个)。在这种情况下,您无需拨打self.__init__
,因为这会再次呼叫Employee.__init__
。您需要编写Person.__init__
(或使用super()
)来显式调用继承的方法。
由于Employee
没有定义自己的Name
方法,Person.Name
是最具体的方法,因此self.Name()
调用的方法就是Employee
。如果Name
定义了自己的self.Name()
,那么Bdt<space>
会调用throw=it,
。