7. Java 中的重载和重写的区别是什么?
大约 3 分钟
在Java中,**重载(Overloading)和重写(Overriding)**是两个重要的概念,它们涉及方法在类内和类间的使用方式。虽然名字相似,但它们的用途和实现机制是不同的。下面是它们的详细区别:
1. 定义
- 重载(Overloading):
- 重载指在同一个类中,可以定义多个方法,这些方法的名称相同,但参数列表(参数的类型、数量或顺序)不同。重载方法可以有不同的返回类型。
- 重载通常用于在同一个类中为不同的输入参数提供不同的实现。
- 重写(Overriding):
- 重写指在子类中定义一个方法,该方法与父类中的方法具有相同的名称、参数列表和返回类型。通过重写,子类可以提供父类方法的具体实现。
- 重写用于在继承关系中通过子类提供父类方法的不同实现。
2. 方法签名
- 重载:
- 方法名相同,参数列表不同(参数的类型、数量或顺序至少有一个不同)。
- 可以有不同的返回类型和访问修饰符。
- 重写:
- 方法名、参数列表和返回类型必须完全相同。
- 重写方法的访问修饰符不能比父类的更严格,但可以更宽松。
3. 发生的范围
重载:
- 重载发生在同一个类中,或者在父类与子类之间,但重载方法仍然属于定义它们的类。
重写:
- 重写发生在子类与父类之间,重写方法取代了父类中被重写的方法。
4. 多态性
- 重载:
- 重载是编译时的多态性(静态多态性)。编译器在编译时根据方法调用的参数列表选择合适的重载方法。
- 重写:
- 重写是运行时的多态性(动态多态性)。在运行时,根据实际对象的类型调用相应的重写方法。
5. 返回类型
- 重载:
- 重载方法可以有相同或不同的返回类型,因为它们的参数列表不同。
- 重写:
- 重写方法必须有相同的返回类型,或者是父类方法返回类型的子类型(协变返回类型)。
6. 访问修饰符
- 重载:
- 重载方法的访问修饰符可以不同,没有特定的限制。
- 重写:
- 重写方法的访问修饰符必须大于或等于父类中被重写的方法的访问修饰符。例如,如果父类方法是
protected
的,子类重写时可以是protected
或public
,但不能是private
。
- 重写方法的访问修饰符必须大于或等于父类中被重写的方法的访问修饰符。例如,如果父类方法是
7. 异常
- 重载:
- 重载方法可以抛出不同的异常,也可以不抛出异常。
- 重写:
- 重写方法可以抛出与父类方法相同的异常,或是更少的异常,但不能抛出新的、更广泛的异常。
8. 示例代码
重载示例:
class Example {
void print(int a) {
System.out.println("Integer: " + a);
}
void print(String a) {
System.out.println("String: " + a);
}
}
重写示例:
class Parent {
void display() {
System.out.println("Parent's display()");
}
}
class Child extends Parent {
@Override
void display() {
System.out.println("Child's display()");
}
}
总结
- 重载:发生在同一类中,通过相同的方法名但不同的参数列表来实现。重载体现了编译时的多态性。
- 重写:发生在子类与父类之间,通过在子类中重新定义父类方法来实现。重写体现了运行时的多态性。
这两者提供了不同层面的多态性,使得Java程序可以更灵活地处理方法调用。