当前位置: 首页 > news >正文

Java学习笔记:方法重写

学完继承之后,我发现一个问题:父类Animal里的eat()方法输出“正在吃东西”,但是狗应该是“正在吃狗粮”,猫应该是“正在吃鱼”。我不想改父类的代码,因为其他动物可能还是需要原来的逻辑。查了一下,方法重写就是解决这个问题的。

理解
重写就是子类对父类的方法不满意,自己重新写一个版本。前提是方法名、参数列表、返回值类型都得一模一样,方法体可以自己定。

一句话:外表不变,内部实现换掉。

重写和重载不一样。重载是在同一个类里,参数不同。重写是子类和父类之间,参数必须一样。

重写的规则
方法名必须相同

参数列表必须相同(数量、类型、顺序)

返回值类型必须相同,或者是父类返回值类型的子类

访问权限不能比父类更严格(public > protected > 默认 > private)

不能重写父类的private方法

不能重写final方法

不能重写static方法(static方法是属于类的,不是对象的)

抛出的异常不能比父类更宽泛

代码示例
java
public class Phone {
protected String brand;
protected double price;

public Phone(String brand, double price) {this.brand = brand;this.price = price;
}public void call(String number) {System.out.println("正在拨号:" + number);System.out.println("手机贴着耳朵通话");
}public void sendMessage(String number, String content) {System.out.println("发送短信给" + number + ":" + content);
}public void showInfo() {System.out.println("品牌:" + brand + ",价格:" + price);
}public Phone getSelf() {return this;
}

}

public class SmartPhone extends Phone {
private String os;

public SmartPhone(String brand, double price, String os) {super(brand, price);this.os = os;
}@Override
public void call(String number) {System.out.println("正在通过4G网络拨号:" + number);System.out.println("扬声器免提通话");System.out.println("同时显示来电悬浮窗");
}@Override
public void sendMessage(String number, String content) {System.out.println("通过微信发送消息给" + number + ":" + content);System.out.println("已读回执已开启");
}public void videoCall(String number) {System.out.println("正在和" + number + "视频通话");
}@Override
public SmartPhone getSelf() {return this;
}public void showOs() {System.out.println("操作系统:" + os);
}

}

public class OldPhone extends Phone {
public OldPhone(String brand, double price) {
super(brand, price);
}

@Override
public void call(String number) {System.out.println("请手动拨号:" + number);System.out.println("等待接通中...");System.out.println("通话声音较小,请靠近听筒");
}@Override
public Phone getSelf() {return this;
}

}

public class TestOverride {
public static void main(String[] args) {
Phone p1 = new Phone("诺基亚", 200);
SmartPhone p2 = new SmartPhone("华为", 5000, "鸿蒙");
OldPhone p3 = new OldPhone("步步高", 150);

    System.out.println("=== 普通手机通话 ===");p1.call("123456");System.out.println("\n=== 智能手机通话 ===");p2.call("123456");System.out.println("\n=== 老年机通话 ===");p3.call("123456");System.out.println("\n=== 发送消息对比 ===");p1.sendMessage("123456", "你好");p2.sendMessage("123456", "你好");System.out.println("\n=== 多态效果 ===");Phone phone1 = new SmartPhone("小米", 4000, "安卓");Phone phone2 = new OldPhone("飞利浦", 300);phone1.call("111111");phone2.call("222222");System.out.println("\n=== 协变返回类型 ===");SmartPhone sp = new SmartPhone("苹果", 8000, "iOS");Phone result1 = sp.getSelf();SmartPhone result2 = sp.getSelf();System.out.println(result2.brand);
}

}
今天踩的坑
我写的错误 为什么错 应该怎么写
重写时参数类型写错了 变成重载了 参数必须一模一样
返回值类型写的不一样 编译报错 相同或子类类型
访问权限写成private 父类是public,不能缩小 保持或扩大
忘记加@Override 手滑写错方法名也不知道 加上注解让编译器帮忙检查
尝试重写static方法 编译不报错但不是重写 static方法属于类,不能重写
重写时抛出新异常 父类没抛异常 要么不抛,要么抛父类也抛的

Override注解的作用
告诉编译器下面这个方法是重写父类的

如果方法名写错或者参数写错,编译器会报错

不加也能重写,但加了更安全

强烈建议每次都写

重写vs重载对比
比较 重写 重载
英文 Override Overload
发生位置 子类和父类 同一个类
方法名 必须相同 必须相同
参数列表 必须相同 必须不同
返回值 相同或子类类型 可以不同
访问权限 不能更严格 无限制
异常 不能更宽泛 无限制
注解 @Override 无专用注解
绑定时机 运行时动态绑定 编译时静态绑定

几个重要发现
子类重写父类方法后,调用的是子类的版本

通过父类引用指向子类对象时,调用的是子类重写后的方法(多态的基础)

可以在重写的方法里用super.方法名()调用父类的版本,然后再加自己的逻辑

private方法不存在重写,子类写一个同名方法只是新方法

final方法不能被重写,String类就是final的

构造器不能被重写,因为构造器名字必须和类名相同

静态方法可以被子类定义同名方法,但这不是重写,叫隐藏

什么时候需要重写

父类的方法逻辑太通用,不适合子类

子类需要增加额外的功能

父类的方法已经过时,子类需要新实现

想要改变方法的默认行为

设计原则提醒
开闭原则:对扩展开放,对修改关闭。通过重写来实现扩展,而不是去改父类的代码。

总结
重写就是子类不满意父类的方法,自己另起炉灶。方法签名不变,内部实现随便换。加上@Override注解,让编译器帮你检查。重写是实现多态的基础,一定要掌握。

http://www.rkmt.cn/news/1305999.html

相关文章:

  • 2026杭州GEO优化公司深度测评:技术源头、实战成果与选型指南 - 速递信息
  • 南充地区喷绘写真、平板UV喷印、亚克力字制作 - 四川华蔓广告有限公司设计安装施工 - 四川华蔓广告有限公司
  • 2026年泉州市面上口碑好的装修公司十大靠谱品牌推荐——深度解析“3F改造家”如何以工匠精神重塑旧房翻新市场 - 速递信息
  • 长沙到岳阳商务车/长沙到岳阳商务车电话/长沙去岳阳商务车/长沙去岳阳商务车电话/黄花机场到岳阳商务车电话/黄花机场去岳阳商务车 - 速递信息
  • 如何优化 MySQL 数据库的查询性能?
  • 2026长沙到岳阳商务车/长沙到岳阳商务车电话/岳阳到长沙商务车/岳阳到长沙商务车电话推荐 - 速递信息
  • 2026年4月热门的鹿优选商城推荐,手机购物/线上购物/护肤品时尚好物优选/好物优选,鹿优选商城商品质量如何 - 品牌推荐师
  • 装饰用
  • docker运行hermes agent
  • 2026涪陵家具工厂推荐|沙发/床垫/定制家具实力厂家汇总 - 企业推荐师
  • 南充地区门头招牌、发光字、软膜灯箱制作 - 四川华蔓广告有限公司设计安装施工 - 四川华蔓广告有限公司
  • 2026年4月技术好的清理筛实力厂家推荐,粮食通风地笼/斗式提升机/悬空输送机/比重精选筛/清理筛,清理筛生产厂家哪个好 - 品牌推荐师
  • 宿主机与vm共享folder的开发
  • 2026年贵州AI网络推广怎么做才不踩坑?贵阳豆包搜索推广5大服务商实战对标指南 - 年度推荐企业名录
  • 物质的本质
  • Nginx 配置 API 网关鉴权失败报错 502 Bad Gateway 如何解决?
  • Java程序中如何ping一个域名是否有效
  • 面向对象程序设计-第一部分总结
  • MIT 开源 ScalarGui 图形化搞定超大 Git 仓库克隆,支持断点续传与稀疏检出
  • 万字 Claude Code 深度实践:安装、工作流与定制化配置详解
  • claude code命令使用
  • 2026年电磁加热厂家/电磁导热油炉厂家/电导热油炉厂家排行 - 速递信息
  • 2026年推荐EDI设备厂,值得信赖的EDI设备维保生产商,推荐EDI设备厂家地址 - 品牌推广大师
  • 2026优选:正规的工程剩余电缆回收哪家好 热门推荐 口碑优选 - 速递信息
  • 面向对象程序设计pta作业集1-3总结Blog - 黑马王子
  • 2026最新:赤峰除甲醛公司哪个专业,哪家更靠谱 - 得意的笑125
  • 2026必看:赤峰甲醛检测治理公司专业之选,如何选择一个真正可靠且有效的除甲醛公司呢? - 得意的笑125
  • OAuth2.0 授权码模式回调地址不匹配报错 invalid_redirect_uri 怎么处理?
  • Node.js Express 中间件鉴权漏掉部分路由导致 403 Forbidden 怎么办?
  • Tlias教学管理系统项目实战