问答文章1 问答文章501 问答文章1001 问答文章1501 问答文章2001 问答文章2501 问答文章3001 问答文章3501 问答文章4001 问答文章4501 问答文章5001 问答文章5501 问答文章6001 问答文章6501 问答文章7001 问答文章7501 问答文章8001 问答文章8501 问答文章9001 问答文章9501

Java 多层super()调用问题

发布网友 发布时间:2022-04-18 20:19

我来回答

8个回答

懂视网 时间:2022-04-19 00:40

注:此处以python 3为运行环境,例子摘自《python cookbook》第8章。

python中若子类要实现父类的初始化,主要有两种方法,第一种是直接通过父类名,第二种是利用super方法。在单继承时两者没什么区别,但在多继承时就需要注意一些细微的差距了。实例解释才是硬道理!
1、利用父类名的情况:

Python代码

class Base:

def __init__(self):

print('Base.__init__')

class A(Base):

def __init__(self):

Base.__init__(self)

print('A.__init__')

class B(Base):

def __init__(self):

Base.__init__(self)

print('B.__init__')

class C(A,B):

def __init__(self):

A.__init__(self)

B.__init__(self)

print('C.__init__')


此时实例化C类会输出如下:

Python代码

>>> c = C()

Base.__init__

A.__init__

Base.__init__

B.__init__

C.__init__

>>>


从中可看出Base类被调用了两次。这想必在很多情况下都不是我们想要的结果,所以此时可考虑用super方法。

2、利用super的情况:

Python代码

class Base:

def __init__(self):

print('Base.__init__')

class A(Base):

def __init__(self):

super().__init__()

print('A.__init__')

class B(Base):

def __init__(self):

super().__init__()

print('B.__init__')

class C(A,B):

def __init__(self):

super().__init__() # Only one call to super() here

print('C.__init__')


此时再实例化C类的输出为:

Python代码

>>> c = C()

Base.__init__

B.__init__

A.__init__

C.__init__

>>>


可看出Base类是不是只调用了一次啊!但很遗憾的是,这并不是促使我写这篇博客记录的原因,因为如果仔细观察的话,虽说Base类的确如预期只调用了一次,但你有没有发觉是先输出“B.__init__”而后才输出的“A.__init__”?而且为什么这样就使得Base只初始化了一次?想必你也有点懵逼了吧?其实这一切都得“怪罪”于super在多继承时的调用过程。python在实现一个类(不仅是继承)时,会产生一个方法生成解析顺序列表,该列表可通过类属性 __mro__ 查看之,如本例中是这样的:

Python代码

>>> C.__mro__

(<class '__main__.C'>, <class '__main__.A'>, <class '__main__.B'>,

<class '__main__.Base'>, <class 'object'>)

>>>


所以在搜索一个属性或方法时,它就会按照这个列表遍历每个类,直到找到第一个匹配这个属性或方法的类为止。而在继承中使用super时,解释器会每遇到一次super就会在该列表上搜索下一个类,直到不再遇到super或列表遍历完为止,然后再类似递归逐层返回。因此本例中搜索过程为:C中遇到super --> 搜索列表中的下一个类,即A --> A中再次遇到super,搜索B --> B中super再现,搜索Base --> 初始化Base类,递归返回。
为了更好的解释该过程,现在请注释掉B类的super所在行:

Python代码

class B(Base):

def __init__(self):

#super().__init__()

print('B.__init__')

class C(A,B):

def __init__(self):

super().__init__() # Only one call to super() here

print('C.__init__')


再次实例化C类,输出如下:

Pythonn代码

>>> c = C()

B.__init__

A.__init__

C.__init__


Base类不再产生输出!为什么?因为B中没了super后,就阻断了列表去搜索Base类,所以也就没有初始化Base了!

热心网友 时间:2022-04-18 21:48

这位同学,想必你是刚刚学java,你这个问题在java中是不会出现的,你看看B继承A,C继承B,你说程序会这么写吗? 既然Java是单继承的,想实现多继承直接使用接口好了,何必这样子呢。程序太不美观了,以后写代码不可能写成这样子的。

如果说你非要弄个明白的话,你可以
class A{
public A(){
system.out.println("调用A的无参构造方法");
}
}
class B{
public B(){
system.out.println("调用B的无参构造方法");
}
}
依次类推,在main方法中建一个类,测试一下到底调用的是哪个就好了?

热心网友 时间:2022-04-18 23:06

如果父类有无参构造方法,即使没有显式调用super()的话,也会自动调用super()的。
如果父类没有无参构造方法,必须显式调用父类的构造方法。

热心网友 时间:2022-04-19 00:41

其实这。。不就是super().super()吗?
要想实现,在B里构造一个调用A()的构造方法getA(),然后在C里面调用super().getA()就行

热心网友 时间:2022-04-19 02:32

同样是super();,当你调用B的构造函数时,B又调用了A的构造函数。追问我说的是B的构造方法里面除了super()外的其他内容都不要执行,而是仅仅调用A的构造方法

追答参考楼上 软件工程师杜天微

热心网友 时间:2022-04-19 04:40

子类只能调用自己直接父类的构造方法~追问只能?!能不能说清楚些,我觉得“软件工程师杜天微”说的也挺有道理的

追答.我和他说的完全是一个意思啊 c类只能决定调用b类的构造方法 而调用a类的构造方法只能又b类来决定

热心网友 时间:2022-04-19 07:05

只有super().这是递归调用.

热心网友 时间:2022-04-19 09:46

同样是 super();追问我说的是仅仅调用A的无参构造方法。如果是这样,那要是调用B的无参构造呢?是不是也是同样是super()呢?

追答你new C的时候,不可能不构建B而直接构建C。
构建C的顺序是 先按照C的大小分配内存 内存的首先构建A,然后构建B,最后才是C。

要构造A,首先要构造B;构造因为你B只有无参构造,所以也只能调用这个。。。
如果你B里面有个
B(String s){ super(); }
那也可以
C(){
super("123");
}

声明声明:本网页内容为用户发布,旨在传播知识,不代表本网认同其观点,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。E-MAIL:11247931@qq.com
国外留学有用吗 花钱出国留学有用吗 !这叫什么号 百万医疗赔付后是否可以续保 前一年理赔过医疗险还能续保吗? 医疗住院险理赔后还能购买吗? 女生多大后可以不在长身高? 如何不用软件把手机投屏到电脑上手机屏幕怎样投放到电脑上 战时拒绝、故意延误军事订货罪既遂的处罚? 战时故意延误军事订货罪处罚标准 麻辣烫是怎么做的有几步 麻辣烫的配方中鸡汤是怎么做的 小谷姐姐麻辣烫汤底是猪骨汤还是牛骨汤? 孙大力骨汤麻辣烫用的是牛骨还是猪骨? qq相册里的好友相册怎么删除 啤酒工艺的最新进展 啤酒新技术 啤酒工业生产的工艺流程包含那几个单元和关键技术? 啤酒生产的核心技术是什么 啤酒生产技术的介绍 其他银行卡可以给建行e账户打钱么 如果我开的户是E账户,那人家像我龙卡通账户转账能收到吗 建行非本人账户不能交易什么意思 什么叫“货物期货”,“期货的实物交割环节纳税”是什么意思?税法高手帮帮忙(注会的问题) 货物期货如何计算增值税 为什么期货交易所本身发生的各项进项不得抵扣,什么叫“本身发生的” 别人可以向我的建行e账户转账吗? 货物期货增值税是什么意思?刚在申银万国开户。 期货交割时的*怎么计算?比如我买的橡胶期货2万元一吨,交割时2.5万,怎么计算*,谢谢 期货是不是只有实物交割才需要交增值税? 结婚利月是怎么个意思?求帮助 大利月是什么意思 小利月是什么意思 什么是“大利月”? 什么是大利月 《摩登小祖宗》txt下载在线阅读全文,求百度网盘云资源 结婚看日子的那个大利月是怎么看的? 小利月是什么意思。 什么叫大利月 怎么谈恋爱呀?我是男生。 大利月是指结婚典礼还是拿结婚证? 有一本小说,是古代玄幻,男主是女主的老祖宗了,女主叫男主皇叔, 不知哪个月为大利月,是阴历还是阳历的?还有为啥这些建议中有些在黄历中说不利于婚嫁呢? 属虎的结婚几月是利月 看日子中的苑大利是什么意思 属羊的大利月和小利月是几月 金立手机屏幕闪屏怎么回事 女若属蛇的话,利月是? 人类将来会怎样被人工智能灭绝? 猪属相的利月是几月 哈弗H4手机互联功能的使用需要注意什么?