本文目录导读:

我来通过一个具体的动物类案例,演示Java子类重写的完整实操过程。
基础案例:动物叫声系统
父类:Animal
// 父类:动物
public class Animal {
protected String name;
protected int age;
// 构造方法
public Animal(String name, int age) {
this.name = name;
this.age = age;
}
// 要被重写的方法
public void makeSound() {
System.out.println("动物发出声音");
}
// 可被重写的移动方法
public void move() {
System.out.println("动物在移动");
}
// final方法不能被重写
public final void sleep() {
System.out.println("动物在睡觉");
}
}
子类1:Dog
// 子类:狗
public class Dog extends Animal {
private String breed; // 品种
public Dog(String name, int age, String breed) {
super(name, age); // 调用父类构造方法
this.breed = breed;
}
@Override
public void makeSound() {
System.out.println(name + "(" + breed + ")说:汪汪汪!");
}
@Override
public void move() {
System.out.println(name + "在欢快地奔跑");
}
// 特有的方法
public void wagTail() {
System.out.println(name + "在摇尾巴");
}
}
子类2:Cat
// 子类:猫
public class Cat extends Animal {
private String color;
public Cat(String name, int age, String color) {
super(name, age);
this.color = color;
}
@Override
public void makeSound() {
System.out.println(name + "(" + color + "色)说:喵喵喵!");
}
@Override
public void move() {
System.out.println(name + "在优雅地走路");
// 也可以调用父类方法
// super.move();
}
// 特化的方法
public void climb() {
System.out.println(name + "在爬树");
}
}
测试类
public class TestOverride {
public static void main(String[] args) {
// 多态:父类引用指向子类对象
Animal animal1 = new Dog("旺财", 3, "金毛");
Animal animal2 = new Cat("咪咪", 2, "橘");
Animal animal3 = new Animal("普通动物", 1);
System.out.println("=== 动物叫声测试 ===");
// 调用重写后的方法
animal1.makeSound(); // 输出:旺财(金毛)说:汪汪汪!
animal2.makeSound(); // 输出:咪咪(橘色)说:喵喵喵!
animal3.makeSound(); // 输出:动物发出声音
System.out.println("\n=== 动物移动测试 ===");
animal1.move(); // 输出:旺财在欢快地奔跑
animal2.move(); // 输出:咪咪在优雅地走路
animal3.move(); // 输出:动物在移动
System.out.println("\n=== 睡觉测试(final方法) ===");
animal1.sleep(); // 输出:动物在睡觉
animal2.sleep(); // 输出:动物在睡觉
// 注意:多态不能调用子类特有的方法
// animal1.wagTail(); // 编译错误!
// 需要向下转型
if (animal1 instanceof Dog) {
Dog dog = (Dog) animal1;
dog.wagTail(); // 可以调用了
}
}
}
运行结果
=== 动物叫声测试 ===
旺财(金毛)说:汪汪汪!
咪咪(橘色)说:喵喵喵!
动物发出声音
=== 动物移动测试 ===
旺财在欢快地奔跑
咪咪在优雅地走路
动物在移动
=== 睡觉测试(final方法) ===
动物在睡觉
动物在睡觉
进阶案例:图形面积计算
// 父类:图形
abstract class Shape {
protected String color;
public Shape(String color) {
this.color = color;
}
// 抽象方法,必须被子类重写
public abstract double getArea();
// 普通方法,可选重写
public void display() {
System.out.println("这是一个" + color + "色的图形,面积:" + getArea());
}
}
// 子类:圆形
class Circle extends Shape {
private double radius;
public Circle(String color, double radius) {
super(color);
this.radius = radius;
}
@Override
public double getArea() {
return Math.PI * radius * radius;
}
@Override
public void display() {
System.out.println("这是一个" + color + "色圆形,半径:" + radius + ",面积:" + getArea());
}
}
// 子类:矩形
class Rectangle extends Shape {
private double width;
private double height;
public Rectangle(String color, double width, double height) {
super(color);
this.width = width;
this.height = height;
}
@Override
public double getArea() {
return width * height;
}
}
// 测试类
public class ShapeTest {
public static void main(String[] args) {
Shape[] shapes = new Shape[3];
shapes[0] = new Circle("红", 5.0);
shapes[1] = new Rectangle("蓝", 4.0, 6.0);
shapes[2] = new Circle("黄", 3.0);
System.out.println("=== 图形面积计算 ===");
for (Shape shape : shapes) {
shape.display(); // 调用重写后的方法
}
}
}
重写规则总结
class Demo {
// 规则1:方法名、参数列表必须相同
// 规则2:返回值类型必须相同或是子类
// 规则3:访问权限不能比父类更严格
// 规则4:不能重写private、final、static方法
// 规则5:异常不能比父类抛出更多
@Override // 推荐使用,编译器会检查重写是否正确
public void exampleMethod() {
// 实现代码
}
}
实操建议
- 使用@Override注解:养成好习惯,避免拼写错误
- 调用父类方法:使用
super.methodName()在子类方法中调用父类版本 - 保持行为一致:重写的方法应该保持与父类方法行为的逻辑一致性
- 利用多态:通过父类引用调用子类重写的方法,提高代码扩展性
通过这个案例,你可以看到重写如何让不同的子类表现出不同的行为,体现了面向对象的多态特性。