1. 主页 > 好文章

Java方法覆盖必须注意的3个问题:返回值、修饰符、异常


??哎我说兄弟们,你们有没有遇到过这种情况???
刚学会继承的概念,兴冲冲地给父类方法写了个覆盖版本,结果编译器直接甩你一脸红色波浪线。这时候是不是特别想摔键盘?稳住别慌,今天咱们就来唠唠方法覆盖里那些「看似简单实则暗藏杀机」的三大坑点!


第一个大坑:返回值玩变脸

??「子类方法的返回值可以随便改吗?」??——这问题就跟问「方便面能当主食天天吃吗」一样危险!咱们得记住:??覆盖方法的返回值要么和父类完全一致,要么是父类返回值的子类??(这叫协变返回类型)。举个栗子:

java复制
// 父类
Animal getAnimal() { return new Animal(); }

// 子类 ?允许
Dog getAnimal() { return new Dog(); }  // Dog是Animal子类

// 子类 ?作死
String getAnimal() { return "旺财"; }  // 直接类型不兼容

??重点来了??:协变返回类型这玩意儿是Java5之后才有的福利,你要是还在用古董级JDK版本,趁早升级吧!新手最容易栽跟头的地方就是自以为能随便改返回值类型,结果被编译器教做人。


第二个拦路虎:修饰符权限

??「我能不能把public方法改成private省事?」??——这想法就跟「为了省电把冰箱门拆了」一样离谱!记住这个铁律:??子类方法的访问权限必须≥父类方法??。具体怎么记?咱们搞个权限等级表对比下:

修饰符开放程度排名
public冠军
protected亚军
默认(不写)季军
private殿军

举个反例你品你细品:

java复制
class 爸爸 {
    public void 给零花钱() { ... }
}

class 儿子 extends 爸爸 {
    // ?大逆不道!居然想缩水权限
    private void 给零花钱() { ... }
}

这代码要是能编译通过,那儿子岂不是能反过来限制老子的权限?Java的设计哲学可不答应!


第三个雷区:异常处理陷阱

??「父类方法抛异常,子类能不能装没事人?」??——这就像「老爸说有雷区,儿子偏要硬闯」!处理异常时有两条黄金准则:

  1. ??抛出的异常类型必须≤父类方法声明的异常??
  2. ??不能抛出父类方法没声明的新受检异常??

举个实际场景:

java复制
// 父类声明
void 转账() throws IOException {...}

// 子类合法操作 ?
void 转账() throws FileNotFoundException {...}  // FileNotFoundException是IOException子类

// 子类骚操作 ?
void 转账() throws SQLException {...}  // 凭空造出新异常类型

??划重点??:运行时异常(RuntimeException)不受这个限制,这也是为什么很多框架喜欢用运行时异常的原因。不过咱们新手还是悠着点,先把基础规则吃透再说!


灵魂拷问环节

??Q:这三个规则记不住怎么办???
A:记不住就写代码时开着IDE的自动提示!现在的IDE(比如IntelliJ IDEA)都会用红色波浪线提醒你哪里犯规了,就跟有个老师傅在旁边盯着你写代码似的。

??Q:万一我就是想突破限制呢???
A:年轻人,听叔一句劝——??继承是契约精神,不是让你为所欲为的??。真想搞事情,可以考虑用组合代替继承,这才是真正的高手思维。


个人碎碎念

干了这么多年Java开发,见过太多人在方法覆盖上翻车。其实这三个规则背后都藏着面向对象设计的智慧:

  • 返回值限制保证了「里氏替换原则」
  • 修饰符规则维护了类的封装性
  • 异常约束确保了代码的可维护性

下次写覆盖方法时,不妨多花30秒检查这三个要点。记住,??代码首先是给人看的,其次才是给机器执行的??,养成好习惯比什么都重要!

本文由嘻道妙招独家原创,未经允许,严禁转载