一、背景介绍
在Java编程中,方法重写是面向对象编程(OOP)的一项重要特性。它允许子类提供对父类方法的具体实现,以便实现多态性。方法重写的主要用途包括:
-
实现多态性:允许在运行时根据对象的实际类型调用相应的方法。
-
增强代码的灵活性:子类可以根据自己的需求修改或扩展父类的方法,而不必修改父类的代码。
-
提高代码的可维护性:通过重写方法,可以集中处理子类特有的行为,使得代码更加清晰。
重要性
-
代码复用:通过继承和重写,子类可以复用父类的代码,减少重复。
-
动态绑定:方法重写使得Java能够在运行时决定调用哪个方法,这为多态性提供了基础。
-
增强功能:子类可以在不改变父类的情况下,增强或修改方法的行为。
生活中的类比
可以将方法重写比作一个公司中的员工(子类)和他们的上司(父类)。上司制定了一个工作流程(父类方法),而员工可以根据自己的工作需要调整这个流程(重写方法)。比如,销售部门的员工可能会在客户服务中添加一些额外的步骤,而技术支持部门的员工则可能会有不同的处理流程。通过这种方式,员工可以在遵循上司的指导的同时,灵活应对不同的工作需求。
二、方法重写的基本概念
1. 基本语法
在Java中,方法重写的基本语法是:在子类中定义一个与父类方法相同的方法名、返回类型和参数列表。重写的方法必须与父类的方法具有相同的签名(即方法名和参数列表)。
基本语法示例:
class Parent {void display() {System.out.println("Display from Parent");}
}class Child extends Parent {@Overridevoid display() {System.out.println("Display from Child");}
}
三、方法重写的应用示例
示例 1:基本的重写示例
示例代码:
// 父类
class Animal {void sound() {System.out.println("Animal makes a sound");}
}// 子类
class Dog extends Animal {@Overridevoid sound() {System.out.println("Dog barks");}
}// 主类
public class Main {public static void main(String[] args) {Animal myDog = new Dog(); // 向上转型myDog.sound(); // 调用重写的方法}
}
代码解释:
-
**父类
Animal
**:-
定义了一个方法
sound()
,输出“Animal makes a sound”。
-
-
**子类
Dog
**:-
使用
extends
关键字继承Animal
类。 -
重写了
sound()
方法,输出“Dog barks”。这里使用了@Override
注解,表示这是一个重写的方法。
-
-
**主类
Main
**:-
创建了一个
Dog
类的对象myDog
,并将其引用赋值给Animal
类型的变量(向上转型)。 -
调用
myDog.sound()
时,实际上调用的是Dog
类中重写的方法,输出“Dog barks”。
-
示例 2:重写带参数的方法
示例代码:
// 父类
class Calculator {// 方法重载:计算两个整数的和int add(int a, int b) {return a + b;}
}// 子类
class ScientificCalculator extends Calculator {// 重写父类的方法,增加一个浮点数参数@Overrideint add(int a, int b) {return a + b; // 调用父类的add方法}// 新增一个方法,计算三个整数的和int add(int a, int b, int c) {return a + b + c;}
}// 主类
public class Main {public static void main(String[] args) {ScientificCalculator calc = new ScientificCalculator();System.out.println("Sum of 2 and 3: " + calc.add(2, 3)); // 调用重写的方法System.out.println("Sum of 2, 3, and 4: " + calc.add(2, 3, 4)); // 调用新方法}
}
代码解释:
-
**父类
Calculator
**:-
定义了一个方法
add(int a, int b)
,计算两个整数的和。
-
-
**子类
ScientificCalculator
**:-
使用
extends
关键字继承Calculator
类。 -
重写了
add(int a, int b)
方法,虽然实现与父类相同,但可以根据需要进行不同的实现。 -
新增了一个方法
add(int a, int b, int c)
,计算三个整数的和。
-
-
**主类
Main
**:-
创建
ScientificCalculator
类的对象calc
,调用重写的方法和新方法,展示了不同的加法实现。
-
示例 3:重写与多态性结合
示例代码:
// 父类
class Shape {void draw() {System.out.println("Drawing a shape");}
}// 子类
class Circle extends Shape {@Overridevoid draw() {System.out.println("Drawing a circle");}
}// 子类
class Square extends Shape {@Overridevoid draw() {System.out.println("Drawing a square");}
}// 主类
public class Main {public static void main(String[] args) {Shape shape1 = new Circle(); // 向上转型Shape shape2 = new Square(); // 向上转型shape1.draw(); // 调用Circle的draw方法shape2.draw(); // 调用Square的draw方法}
}
代码解释:
-
**父类
Shape
**:-
定义了一个方法
draw()
,输出“Drawing a shape”。
-
-
**子类
Circle
**:-
重写了
draw()
方法,输出“Drawing a circle”。
-
-
**子类
Square
**:-
重写了
draw()
方法,输出“Drawing a square”。
-
-
**主类
Main
**:-
创建
Circle
和Square
类的对象,并将其引用赋值给Shape
类型的变量(向上转型)。 -
调用
shape1.draw()
和shape2.draw()
时,分别调用了Circle
和Square
类中的重写方法,展示了多态性的特性。
-
四、方法重写的注意事项
-
方法签名:重写的方法必须与父类的方法具有相同的方法名、返回类型和参数列表。
-
访问修饰符:重写的方法的访问修饰符必须与父类的方法相同或更宽松(例如,父类方法是
protected
,子类可以是protected
或public
)。 -
不能重写静态方法:静态方法属于类而不是实例,因此不能被重写,只能被隐藏。
-
不能重写final方法:如果父类的方法被声明为
final
,则不能在子类中重写。