Java方法重写必知:5个常见错误与规避方法
(开篇暴击)
??"为什么我的@Override注解突然变黄了?"??、"明明照着教程写的代码,运行结果就是不对!"——这些抓狂瞬间,老程序员看了都直呼内行。今天咱们就把这些坑一个个填平,保你以后少掉几根头发!
一、访问权限越改越小(父类public你改private)
??这是新人最容易翻车的地方??,就像给自家大门装了三道锁,结果钥匙全丢了。
??踩坑现场还原??
父类里写着public void sendMessage()
,子类心血来潮改成private void sendMessage()
。这时候编译器会直接甩脸子:"error: 正在尝试分配更低的访问权限"
??避坑指南??
记住这个口诀:??"父宽子严,立马翻船"??。访问权限只能越改越开放:
- public → 必须保持public
- protected → 可以改成public
- 默认权限 → 可以改成protected或public
举个正确例子:
java复制class Parent { protected void backupData() { /*...*/ } } class Child extends Parent { @Override public void backupData() { /* 这里改成public完全OK */ } }
二、方法签名对不上(参数/返回类型暗搓搓改动)
??这种错误就像做菜忘放盐??,表面看着没问题,实际完全不是那个味。
??典型翻车姿势??
父类方法:void connect(String ip)
子类改成:void connect(String ip, int port)
→ 这根本不是重写,而是新建了个方法!
??救命技巧??
- 必须使用@Override注解(这是你的护身符!)
- 用IDE的自动生成功能(IntelliJ按Ctrl+O,Eclipse按Alt+Shift+S)
- 检查返回类型:基本类型必须完全一致,引用类型可以是父类返回类型的子类
比如这样就不会错:
java复制class Animal { public Number getAge() { return 18; } } class Dog extends Animal { @Override public Integer getAge() { return 2; } // Integer是Number的子类,合法! }
三、跟静态方法较劲(误把隐藏当重写)
??静态方法根本不是重写的菜??,这个知识点坑过无数英雄好汉。
??大型迷惑现场??
java复制class Parent { static void print() { System.out.println("父类静态"); } } class Child extends Parent { static void print() { System.out.println("子类静态"); } // 这是隐藏,不是重写! }
这时候用Parent p = new Child(); p.print();
输出的还是父类版本!
??正确打开方式??
- 记住静态方法属于类,不属于对象
- 想修改静态方法行为?直接类名调用最靠谱
- 实在要用多态效果,改用实例方法
四、异常处理放飞自我(乱抛新异常)
??异常处理不讲究,分分钟让你程序崩溃??。
??危险操作示范??
父类方法声明:void readFile() throws IOException
子类改成:void readFile() throws SQLException
→ 直接报错没商量!
??安全守则??
- 子类方法抛出的异常必须是父类异常的子类
- 可以少抛或不抛异常,但不能新增更宽泛的异常
- 运行时异常不受限制(但也要谨慎使用)
看个合规操作:
java复制class Parent { void process() throws FileNotFoundException { /*...*/ } } class Child extends Parent { @Override void process() { /* 完全不抛异常,合法! */ } }
五、无视final封印(强行修改不可变方法)
??final方法就像被封印的古籍??,谁碰谁倒霉。
??作死行为实录??
java复制class Parent { public final void securityCheck() { /*...*/ } } class Child extends Parent { @Override // 这里会直接报错! public void securityCheck() { /* 想搞事情?没门! */ } }
编译器会直接甩你一脸错误:Cannot override the final method
??生存法则??
- 看到final方法绕道走
- 想修改final方法的行为?考虑用组合替代继承
- 重要核心方法才用final,别随便给自己挖坑
老司机经验加油站
这些年带团队见过太多奇葩错误,最离谱的一次是新人把equals
方法重写成public boolean equals(MyClass obj)
,导致整个系统的对象比较全乱了套。所以特别提醒:??重写Object类方法时,参数类型必须是Object!??
还有个冷知识:重写方法的??返回类型协变??特性是Java5才加入的。所以如果你看到老代码里子类方法返回类型和父类完全一致,别觉得人家不懂,可能是为了兼容旧版本。
最后送大家一句话:??"重写不是乱写,继承要有底线"??。把这些规则吃透,下次遇到问题至少能快速定位方向。毕竟在编程世界里,知道哪里不能踩往往比知道捷径更重要,你说是不是这个理?
本文由嘻道妙招独家原创,未经允许,严禁转载