首页 > 解决方案 > 如果不调用父构造函数(与 Java 不同),多态性如何在 Python 中工作?

问题描述

因此,在 Java 中调用父类构造函数,但在 Python 中不调用。如果这意味着没有创建父对象,那么如何def function在 Python 中成功调用 - 这里发生了什么?

Python代码

class Parent:
    def __new__(self):
        print(f"I am the real parent constructor Hahahah {self}")
        return object.__new__(self)

    def __init__(self):
        print(f"I am the constructor of parent {self}")

    def function(self):
        print(f"I am parent's member function and my self value is {self}")

    def over(self):
        print(f"I am parent's O-function and my self value is {self}")

class Child(Parent):
    def __new__(self):
        print(f"I am the real chid constructor Hahahah {self}")
        return object.__new__(self)

    def __init__(self):
        print(f"I am the initialize of child {self}")

    def over(self):
        print(f"I am the child's member O-function and my self value is {self}")

ch = Child()
ch.over()
ch.function()

以上 Python 代码的输出。注:I am the real parent constructor Hahahah未打印。

I am the real chid constructor Hahahah <class '__main__.Child'>
I am the initialize of child <__main__.Child object at 0x7f4bb5d997b8>
I am the child's member O-function and my self value is <__main__.Child object at 0x7f4bb5d997b8>
I am parent's member function and my self value is <__main__.Child object at 0x7f4bb5d997b8>

类似的Java代码

public class main {

    public static void main(String[] args) {
        Child ch = new Child();
        ch.over();
        ch.function();
    }
}

class Parent {
    Parent () {
        System.out.println("In the parent class constructor | " + this);
    }

    public void function () {
        System.out.println("In the member function of parent | " + this);
    }

    public void over () {
        System.out.println("In the member O-function of parent | " + this);
    }
}

class Child extends Parent {
    Child () {
        System.out.println("I the child class constructor | " + this);
    }

    public void over () {
        System.out.println("In the member O-function of chlid | " + this);
    }
}

上述 Java 代码的输出

In the parent class constructor | code.Child@2a139a55
I the child class constructor | code.Child@2a139a55
In the member O-function of chlid | code.Child@2a139a55
In the member function of parent | code.Child@2a139a55

标签: javapythoninheritancepolymorphism

解决方案


Python 和 Java 是不同的。

在 Java中,扩展类必须始终调用父构造函数。为了方便起见,如果父构造函数没有参数,它将首先自动调用。现在,如果您要向 JavaParent构造函数添加一个参数,如下所示:

Parent (int i) {
    System.out.println("In the parent class constructor | " + this);
}

你会发现如下编译错误:

There is no default constructor available in 'org.example.Parent'

这是有道理的,当构造 Child Java 时不知道将什么作为 value 传递i。所以我们必须手动调用 Parent 构造函数:

Child () {
    super(1);
    System.out.println("I the child class constructor | " + this);
}

Python不那么严格。始终调用父构造函数仍然是一种好习惯,但 Python 不会要求您这样做。这是因为 Python 不是类型安全的。

现在让我们看看如果忘记调用父构造函数会发生什么:

class Parent:
    def __init__(self):
        self.i = 1
        print(f"I am the constructor of parent {self}")

    def printi(self):
        print(self.i)

class Child(Parent):

    def __init__(self):
        pass

ch = Child()
ch.printi()

将发生致命错误:

Traceback (most recent call last):
  File "test.py", line 15, in <module>
    ch.printi()
  File "test.py", line 7, in printi
    print(self.i)
AttributeError: 'Child' object has no attribute 'i'

要修复此代码,您可以将以下行添加到 Child init函数:

Parent.__init__(self)

正如您所注意到的,仍然创建了 Parent 类(因为您可以调用该function方法。这又是因为 Python 不那么严格。在 python 中,可以在不调用构造函数的情况下创建对象。


推荐阅读