super关键字的正确使用:Java继承方法调用指南
你是不是经常遇到这种情况?辛辛苦苦写了个子类,结果发现父类的方法死活调不动,控制台连个错误提示都没有。哎,这破问题我当年初学Java时也踩过坑,今天咱们就来好好唠唠这个??super关键字??到底该怎么用才不翻车。
前两天还有个哥们问我:"为啥我的子类对象调用方法时,父类里的代码不执行啊?"——这其实就是??方法重写??后没正确处理父子类关系的典型症状。新手如何快速涨粉?哦不,说错了,新手如何快速掌握这个知识点?往下看就对了。
一、super到底是个啥玩意?
咱们先看个活生生的例子。假设你爹(父类)会做饭,你(子类)继承了他的厨艺,但是想加点创新:
java复制class Father { void cook() { System.out.println("煮白米饭"); } } class Son extends Father { @Override void cook() { // 这里不加super会怎样? System.out.println("加两个荷包蛋"); } }
这时候你new个Son对象调用cook(),控制台只会打印"加两个荷包蛋",爹的煮饭技能凭空消失了!这时候就需要??super.cook()??来救场,就像这样:
java复制super.cook(); // 先让老爹把饭煮了 System.out.println("加两个荷包蛋");
二、必须用super的3种场景
-
??重写方法还想用父类功能时??
就像上面的做饭例子,不加super就彻底覆盖父类方法,跟断绝父子关系似的 -
??调用父类构造方法时??
这里有个大坑:子类构造方法??必须??先调用父类构造器,你不写的话Java会偷偷给你加个super()
java复制public Son() { super(); // 就算你不写,编译器也会悄悄加上 // 你的初始化代码... }
- ??父类有同名属性时??
如果父子类都有个String name,在子类里想拿到老爹的名字就得用??super.name??
三、新手最容易犯的5个错误
我整理了个对比表格,你们感受下:
错误操作 | 正确姿势 | 引发的后果 |
---|---|---|
忘记写super() | 构造方法首行显式调用 | 编译报错:找不到父类默认构造器 |
在静态方法里用super | 改用类名调用父类静态方法 | 直接编译卡死 |
跨层级调用爷爷辈的方法 | 老老实实逐层super | 想调用爷爷的method?没门! |
在Lambda里用super | 改用方法引用或匿名内部类 | 语法直接不支持 |
以为super能调用叔父类方法 | 只能直系父类 | Java不支持多继承,别做梦了 |
四、灵魂拷问环节
??Q:super能不能用在main方法里???
想啥呢!main是static方法,这时候连对象都没创建,super根本找不到归属。就像你还没出生就想继承老爹的房产证,可能吗?
??Q:父类方法被final修饰了怎么办???
凉拌!final方法就像上了锁的保险箱,子类连重写的权利都没有,更别说用super调用了。这时候只能另辟蹊径,比如重新定义个新方法。
??Q:我同时继承多个父类行不行???
醒醒,Java是单继承的!虽然能用接口实现类似效果,但super永远只能指向那个唯一的亲爹。
五、那些年我踩过的坑
记得有次做电商项目,支付模块的父类有个核心校验方法。我手贱在子类重写时忘了加super,结果凌晨三点被报警短信吵醒——所有订单的金额校验都失效了!血的教训告诉我们:??关键业务代码里用super,最好在方法开头就调用??,就像这样:
java复制@Override void validatePayment() { super.validatePayment(); // 先走完父类校验 // 再添加子类特有的风控逻辑 checkRiskControl(); }
六、小编的私房建议
说实在的,刚开始用super时总觉得它像个监视自己的老古板。但混久了发现,这玩意儿其实是个护身符。我现在养成了三个习惯:
- 重写方法时??先无脑敲super.xxx()??,再写新增逻辑
- 构造方法里??显式写出super()??,哪怕参数为空
- 遇到继承问题先??F12看源码??,别急着瞎猜
最后说句掏心窝的话:别老想着搞什么骚操作,Java设计super的本意就是??防止你们这些新手把继承关系玩崩了??。老老实实按规范来,等真正吃透面向对象再玩高级的,它不香吗?
本文由嘻道妙招独家原创,未经允许,严禁转载