很多 Java 新手小白在学习面向对象编程时,经常会对“重载”和“重写”这两个概念感到困惑。它们看似相似,实则区别很大。
今天,本文就用通俗易懂的语言,结合实际例子,为大家详细讲解 Java 中的重载和重写。
一、 重载 (Overload)
重载是指在同一个类中,定义多个名称相同但参数列表不同的方法。参数列表的不同可以体现在参数的个数、类型或顺序上。
想象一下,你去餐厅吃饭,菜单上有各种菜品,比如:
-
鱼香肉丝 (不辣)
-
鱼香肉丝 (微辣)
-
鱼香肉丝 (中辣)
-
鱼香肉丝 (特辣)
虽然菜名都叫“鱼香肉丝”,但你可以根据自己的口味选择不同的辣度。这就是生活中的“重载”。
代码示例
public class Restaurant {
// 不辣的鱼香肉丝
public void orderYuXiangRouSi() {
System.out.println("您点的是不辣的鱼香肉丝。");
}
// 微辣的鱼香肉丝
public void orderYuXiangRouSi(String spicyLevel) {
System.out.println("您点的是" + spicyLevel + "的鱼香肉丝。");
}
// 例如,可以根据人数点不同分量的鱼香肉丝
public void orderYuXiangRouSi(int peopleCount) {
System.out.println("您点了" + peopleCount + "人份的鱼香肉丝。");
}
// 还可以根据辣度和人数点餐
public void orderYuXiangRouSi(String spicyLevel, int peopleCount) {
System.out.println("您点了" + peopleCount +"人份" + spicyLevel + "的鱼香肉丝。");
}
public static void main(String[] args) {
Restaurant restaurant = new Restaurant();
restaurant.orderYuXiangRouSi(); // 调用不带参数的方法
restaurant.orderYuXiangRouSi("微辣"); // 调用带辣度参数的方法
restaurant.orderYuXiangRouSi(3); // 调用带人数参数的方法
restaurant.orderYuXiangRouSi("中辣", 2); // 调用带辣度和人数参数的方法
}
}
在上面的代码中,orderYuXiangRouSi() 方法根据参数个数和类型的不同,提供了多种点餐选择。
在实际开发中,我们经常需要根据不同的参数类型或数量执行不同的逻辑。例如:
public class Calculator {
public int add(int a, int b) {
return a + b;
}
public double add(double a, double b) {
return a + b;
}
public int add(int... numbers) {
int sum = 0;
for (int number : numbers) {
sum += number;
}
return sum;
}
}
上面的 Calculator 类中,add() 方法根据传入参数的不同,实现了整数、浮点数以及多个数字的加法运算。
二、 重写 (Override)
重写是指子类重新定义父类中已存在的方法。重写要求子类方法与父类方法具有相同的方法名、参数列表和返回类型 (Java 5 后允许返回类型是协变的)。
你可以把“继承”想象成父子关系。父亲会做饭,儿子也会做饭,但儿子做的饭可能和父亲的味道不一样。这就是生活中的“重写”。
代码示例
class Animal {
public void makeSound() {
System.out.println("动物发出声音");
}
public void eat(){
System.out.println("动物正在进食");
}
}
class Cat extends Animal {
@Override
public void makeSound() {
System.out.println("喵喵喵");
}
@Override
public void eat(){
System.out.println("猫咪使用猫粮进食");
}
}
class Dog extends Animal {
@Override
public void makeSound() {
System.out.println("汪汪汪");
}
@Override
public void eat(){
System.out.println("狗狗使用狗粮进食");
}
}
public class Test {
public static void main(String[] args) {
Animal animal = new Animal();
animal.makeSound(); // 输出:动物发出声音
animal.eat(); // 输出:动物正在进食
Cat cat = new Cat();
cat.makeSound(); // 输出:喵喵喵
cat.eat(); // 输出:猫咪使用猫粮进食
Dog dog = new Dog();
dog.makeSound(); // 输出:汪汪汪
dog.eat(); // 输出:狗狗使用狗粮进食
}
}
在上面的代码中,Cat 类和 Dog 类都继承了 Animal 类,并分别重写了 makeSound() 方法和 eat() 方法, 使其拥有了各自的声音和进食习惯。
在图形界面开发中,我们经常需要重写父类的 paint() 方法来实现自定义的绘图逻辑。例如:
import javax.swing.*;
import java.awt.*;
public class MyPanel extends JPanel {
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
// 自定义绘图逻辑,例如绘制一个红色的矩形
g.setColor(Color.RED);
g.fillRect(10, 10, 50, 50);
}
}
上面的代码中,MyPanel 类继承自 JPanel 类,并重写了 paintComponent() 方法,实现了自定义的绘图逻辑。
三、 重载和重写的区别
四、 总结
重载和重写都是 Java 中非常重要的概念,掌握它们对于理解面向对象编程至关重要。希望通过本文的讲解,大家能够清晰地理解这两个概念,并在实际编程中灵活运用。