在Java编程中,理解重载(Overloading)和重写(Overriding)是非常重要的,它们分别在编译期和运行期提供了不同的多态性。以下我们详细剖析这两个概念,并通过实例代码和实际应用场景来帮助理解。
重载(Overloading)
重载发生在同一个类中,允许同一个方法名有不同的参数列表。重载的目的是提高方法的可读性和通用性。重载的实际应用可以是构造函数的重载、不同类型参数的处理等。
特点:
- 方法名相同。
- 参数列表不同(参数类型、参数个数、参数顺序至少有一个不同)。
- 返回类型和访问修饰符可以不同。
示例代码:
java
public class OverloadExample {
// 重载方法:无参数
public void display() {
System.out.println("无参数方法");
}
// 重载方法:一个整数参数
public void display(int a) {
System.out.println("一个整数参数: " + a);
}
// 重载方法:两个参数,类型不同
public void display(int a, String b) {
System.out.println("两个参数: " + a + ", " + b);
}
// 重载方法:两个参数,顺序不同
public void display(String b, int a) {
System.out.println("两个参数,顺序不同: " + b + ", " + a);
}
}
实际应用场景:
构造函数重载是非常常见的例子。当我们需要为类提供多个初始化方式时,使用构造函数重载可以简化代码并提高灵活性。
java
public class Employee {
private String name;
private int age;
// 无参数构造函数
public Employee() {
this.name = "Unknown";
this.age = 0;
}
// 一个参数构造函数
public Employee(String name) {
this.name = name;
this.age = 0;
}
// 两个参数构造函数
public Employee(String name, int age) {
this.name = name;
this.age = age;
}
}
重写(Overriding)
重写发生在子类与父类之间,是子类对父类方法的重新实现。重写的目的是实现动态多态性,使得子类可以根据自己的需要重新定义父类的方法。
特点:
- 方法名相同,参数列表相同。
- 返回类型应相同或是父类返回类型的子类。
- 访问修饰符应大于或等于父类方法。
- 抛出的异常应小于或等于父类方法。
- 父类方法不能是
private
、final
或static
。
示例代码:
java
class Animal {
public void sound() {
System.out.println("动物发出声音");
}
}
class Dog extends Animal {
@Override
public void sound() {
System.out.println("狗叫: 汪汪");
}
}
实际应用场景:
在实际开发中,重写经常用于实现不同的行为。例如,图形库中的draw()
方法可以被不同的图形类(如Circle
、Rectangle
)重写,以实现各自的绘制逻辑。
java
abstract class Shape {
abstract void draw();
}
class Circle extends Shape {
@Override
void draw() {
System.out.println("绘制圆形");
}
}
class Rectangle extends Shape {
@Override
void draw() {
System.out.println("绘制矩形");
}
}
总结
区别点 | 重载方法 | 重写方法 |
---|---|---|
发生范围 | 同一个类 | 子类与父类 |
参数列表 | 必须不同 | 必须相同 |
返回类型 | 可以不同 | 应相同或是父类返回类型的子类 |
抛出异常 | 可以不同 | 应小于或等于父类方法 |
访问修饰符 | 可以不同 | 应大于或等于父类方法 |
发生阶段 | 编译期 | 运行期 |
方法的重写要遵循“两同两小一大”:
- “两同”:方法名相同、形参列表相同;
- “两小”:子类方法返回值类型应比父类方法返回值类型更小或相等,子类方法声明抛出的异常类应比父类方法声明抛出的异常类更小或相等;
- “一大”:子类方法的访问权限应比父类方法的访问权限更大或相等。
特别说明重写的返回值类型:
如果方法的返回类型是引用类型,重写时可以返回该引用类型的子类。
java
class Hero {
public String name() {
return "超级英雄";
}
public Hero getHero() {
return new Hero();
}
}
class SuperMan extends Hero {
@Override
public String name() {
return "超人";
}
@Override
public SuperMan getHero() {
return new SuperMan();
}
}
通过上述例子和解释,我们可以更清楚地理解重载和重写的区别和应用场景,在实际开发中合理使用这两种技术可以大大提高代码的可读性和可维护性。