java - 如果不调用父构造函数(与 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
解决方案
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 中,可以在不调用构造函数的情况下创建对象。
推荐阅读
- angular - 如何在 Angular 中测试来自 RXJS 的地图和分接管道
- redux - 如何处理让用户知道我正在等待 Redux 中 DB 的响应?
- reactjs - 寻找使用 GraphQL 数据在 MapBox 中显示标记的方法
- mysql - 担心在大表上添加新索引
- c# - 在 oxyplot 中绘制字符串列表,其中 YAxis 是字符串,XAxis 是整数
- android - 带有final修饰的JAVA方法变量如何用smali表示?
- python - Python Memory Error - 优化来自scraper的部分代码,以减少内存使用
- typescript - Apollo Server 和 TypeScript:“GraphQLApi”类型与“DataSource”类型没有共同的属性