子类是否需要构造函数/初始化程序?

时间:2019-10-09 12:57:56

标签: python python-3.x class inheritance

通常,当我看到一个子类时,它会在构造函数中调用超类,如下所示:

class Boss(object):
    def __init__(self, name, attitude, behaviour, face):
        self.name = name
        self.attitude = attitude
        self.behaviour = behaviour
        self.face = face

    def get_attitude(self):
        return self.attitude

    def get_behaviour(self):
        return self.behaviour

    def get_face(self):
        return self.face

class GoodBoss(Boss):
    def __init__(self, name, attitude, behaviour, face):
        super().__init__(name, attitude, behaviour, face)

但是在website上,我看到了一个子类的示例:

class Parent(object):
    def __init__(self):
        self.value = 5

    def get_value(self):
        return self.value

class Child(Parent):
    pass 

在最后一个示例中,为什么Child子类不包含super().__init__()

3 个答案:

答案 0 :(得分:3)

尝试理解以下简单代码:

class Parent(object):
    def __init__(self):
        print('Parent is called!')


class ChildA(Parent):
    pass 


class ChildB(Parent):
    def __init__(self):
        print('ChildB is called!')


class ChildC(Parent):
    def __init__(self):
        print('ChildC is called!')
        super().__init__()


p = Parent()
print()
ca = ChildA()
print()
cb = ChildB()
print()
cc = ChildC()
print()


print(ChildA.mro())
print(ChildB.mro())
print(ChildC.mro())

输出:

Parent is called!

Parent is called!

ChildB is called!

ChildC is called!
Parent is called!

[<class '__main__.ChildA'>, <class '__main__.Parent'>, <class 'object'>]
[<class '__main__.ChildB'>, <class '__main__.Parent'>, <class 'object'>]
[<class '__main__.ChildC'>, <class '__main__.Parent'>, <class 'object'>]

主要观察结果

  1. 如果类没有实现__init__()的方法,则其父类的__init__()将被称为 if (存在)。
  2. 如果类具有__init__()方法的实现,则将调用它。但是,其父级的__init__()不会被自动调用。
  3. 如果类具有__init__()方法的实现,则将调用它。我们可以使用__init__()
  4. 显式调用其父级的super().method(*args, **kwargs)方法

答案 1 :(得分:1)

类完全不需要严格的__init__()方法。您可以拥有仅包含类/静态属性/方法的类,并且该类同样有效,尽管其用处尚待商debate。

看到大多数类具有__init__()方法的原因是因为在大多数情况下,实例化一个类时,您都想使用一些值/处理来初始化该类。如果您的Child类与Parent的{​​{1}}方法没有什么不同,则无需重新定义__init__()

如果__init__()类需要重新定义Child,但仍想依靠__init__的{​​{1}}方法,那么您就需要Parent

答案 2 :(得分:0)

在第一个示例中,子类正在构造函数方法中调用父类的 init 方法。当我们需要设置子类方法的某些属性时,但在调用超类方法之后/之前,该方法基本上被使用。让我们考虑以下示例,在子类中设置 age 属性:

class Boss(object):
    def __init__(self, name, attitude, behaviour, face):
        self.name = name
        self.attitude = attitude
        self.behaviour = behaviour
        self.face = face

    def get_attitude(self):
        return self.attitude

    def get_behaviour(self):
        return self.behaviour

    def get_face(self):
        return self.face

class GoodBoss(Boss):
    def __init__(self,
            name,
            attitude,
            behaviour,
            face, age):
        super().__init__(name, attitude, behaviour, face)
        self.age = age # here age is an attribute of only GoodBoss class, Not Superclass

在这里您的子类将设置age属性,该属性不是父类的属性。当您的子类在构造函数中执行的操作与超类不同时,将使用此模式。

在第二个示例中,我们没有在子类的构造函数中设置/调用任何方法。当我们创建子类的对象时,将调用父类的 init 函数。您的子类没有任何不同。

这些完全取决于代码设计。