Python中继承的基础知识

时间:2015-09-22 21:24:24

标签: python python-2.7

我试图了解继承如何在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中工作?

3 个答案:

答案 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,