
嘻道奇闻
- 文章199742
- 阅读14625734
Java子类调用父类方法详解:super关键字的3种使用场景
"哎,你说这Java里的super到底是个啥玩意儿?为啥子类非得用它才能调用父类的方法?"——上周有个刚学Java的学弟抓着头发问我。今天咱们就掰开了揉碎了,把这个让无数新手挠头的知识点彻底讲明白!
一、先搞懂基础:super到底是个啥?
(敲黑板)??super可不是超人,而是子类和父类之间的传话筒??。想象一下你继承了你爸的房产证,但想修改房子装修方案时,是不是得先确认原始户型图?这时候super就是那个帮你翻出父类原始图纸的工具。
举个活生生的例子:
java复制class 老手机 { void 打电话() { System.out.println("嘀——正在拨号..."); } } class 智能手机 extends 老手机 { @Override void 打电话() { super.打电话(); // 先执行父类的基础拨号 System.out.println("正在加载视频通话功能..."); } }
这时候智能手机的打电话功能,既保留了老手机的拨号声,又新增了视频通话。??这就是super最典型的应用场景——在方法重写时保留父类原有功能??。
二、三种必会的super使用姿势
场景1:当儿子想用老爸的绝活时
(拍大腿)这个场景最常见!比如你重写了父类方法,但突然又想用回原版功能。这时候就像做菜时想加点祖传秘方,必须得从父类的调料罐里取。
看这个代码案例:
java复制class 厨师长 { String 做招牌菜() { return "红烧狮子头"; } } class 徒弟 extends 厨师长 { @Override String 做招牌菜() { String 基础版 = super.做招牌菜(); return 基础版 + "(创新版:加入芝士夹心)"; } }
??关键点??:先用super拿到父类方法的结果,再在这个基础上做创新,这才是继承的正确打开方式。
场景2:装修房子先得打地基——构造方法调用
(扶眼镜)这个最容易出错!很多新手不知道,??子类构造方法的第一句,默认就有个隐形的super()??。就像盖房子必须先打地基,不管你要不要装修,地基都得存在。
来看个典型错误示范:
java复制class 父亲 { 父亲(int 存款) { System.out.println("给儿子留了" + 存款 + "万"); } } class 儿子 extends 父亲 { 儿子() { // 这里会报错!因为父类没有无参构造 System.out.println("开始败家..."); } }
正确姿势应该是:
java复制儿子() { super(100); // 必须显式调用父类有参构造 System.out.println("开始败家..."); }
??血泪教训??:当父类没有无参构造时,子类必须手动调用super(...),否则编译器会直接甩脸子给你看!
场景3:翻老爸的旧账本——访问父类属性
(拍桌子)这个冷门但实用!当父子类有同名属性时,就像家里有两个同款保险箱,这时候super就是打开父类那个的钥匙。
举个现实案例:
java复制class 老爸的记账本 { int 存款 = 5000; } class 儿子的记账本 extends 老爸的记账本 { int 存款 = 30000; void 查账() { System.out.println("明面上的存款:" + this.存款); System.out.println("老爸藏的私房钱:" + super.存款); } }
运行结果:
明面上的存款:30000
老爸藏的私房钱:5000
??注意??:这种操作虽然能用,但就像翻老爸的私房钱一样,建议少用,容易破坏封装性。
三、那些年我踩过的super坑(血泪经验包)
- ??不要在静态方法里用super??:就像不能用普通钥匙开保险柜,static方法是类级别的,super是对象级别的
- ??super不是变量名??:有人试图把super当参数传递,结果直接收到编译器警告信
- ??多层继承慎用super??:爷爷类的方法用super.super调用?醒醒,Java压根不支持这种操作!
最近帮人排查的一个真实bug:有个小哥在重写Spring的Bean初始化方法时,忘记调用super.postProcessBeanFactory(),导致整个项目的依赖注入全挂了。你看,??框架源码里处处都是super的踪迹??,这个知识点真不是闹着玩的!
个人观点时间
(点烟)说句掏心窝子的话:super就像做菜时的盐,放少了没味道,放多了齁得慌。新手最容易犯两个极端——要么完全不用导致功能缺失,要么滥用导致代码混乱。
我见过最离谱的代码,在同一个方法里连续调用了5次super.method(),问为啥这么写,答曰"怕没生效"。其实??super调用一次就够,又不是拜年要给多次红包??!
最后给个忠告:当你在子类写代码时,如果感觉某个地方非用super不可,先停下来想想——是不是父类设计得不够合理?好的继承关系应该像接力赛,父类把该传的棒子都传到位,子类只要安心跑自己的赛段就行。