目录
1. 重载及其示例代码
1.1 重载(Overload)
1.2 示例代码
2. 重写及其示例代码
2.1 重写(Override)
2.2 示例代码
3. 总结
方法的重载和重写都是实现多态的方式,区别在于前者实现的是编译时的多态性,而后者实现的是运行时的多态性。
1. 重载及其示例代码
1.1 重载(Overload)
- 定义:方法重载是指在同一个类中,允许定义多个同名方法,只要它们的参数列表不同(参数的类型、数量或顺序不同)。返回类型可以相同也可以不同。
- 目的:重载的主要目的是为了提供相同功能但参数不同的方法。
- 规则:重载的方法必须有不同的参数列表,编译器通过参数列表来区分不同的重载方法。
- 返回类型:方法的返回类型不影响重载,即使两个方法的返回类型不同,只要参数列表不同,它们也可以是重载的。
1.2 示例代码
class Animal {
// 重载方法:不同的参数列表
void makeSound() {
System.out.println("Some sound");
}
void makeSound(String sound) {
System.out.println(sound);
}
}
public class TestOverloading {
public static void main(String[] args) {
Animal myAnimal = new Animal();
myAnimal.makeSound(); // 输出:Some sound
myAnimal.makeSound("Hello"); // 输出:Hello
}
}
在这个例子中,
makeSound
方法被重载了两次,一次没有参数,另一次接受一个String
类型的参数。尽管它们的返回类型相同,但因为参数列表不同,所以它们是重载的方法。
2. 重写及其示例代码
2.1 重写(Override)
- 定义:方法重写是指在子类中重新定义父类的方法。子类重写的方法必须有相同的方法名、参数列表和返回类型。
- 目的:重写的目的是为了改变父类方法的行为,或者提供更适合子类的方法实现。
- 规则:重写的方法必须有相同的方法名和参数列表,返回类型必须相同或者是父类返回类型的子类型(协变返回类型)。
- 访问权限:重写的方法不能拥有比父类方法更严格的访问权限。
- 异常:重写的方法不能抛出新的检查异常或者比父类方法声明的更宽泛的异常。
2.2 示例代码
class Animal {
void makeSound() {
System.out.println("Some sound");
}
}
class Dog extends Animal {
// 重写方法:相同的方法名、参数列表和返回类型
@Override
void makeSound() {
System.out.println("Bark");
}
}
public class TestOverriding {
public static void main(String[] args) {
Animal myDog = new Dog();
myDog.makeSound(); // 输出:Bark
}
}
在这个例子中,
Dog
类继承自Animal
类,并重写了makeSound
方法。因为Dog
类的makeSound
方法有相同的方法名、参数列表和返回类型,所以它重写了父类Animal
的makeSound
方法。
3. 总结
重载发生在一个类中,同名的方法如果有不同的参数列表(参数类型不同、参数个数不同或者二者都不同)则视为重载;重写发生在子类与父类之间,重写要求子类被重写方法与父类被重写方法有相同的返回类型,比父类被重写方法更好访问,不能比父类被重写方法声明更多的异常(里氏代换原则)。
补充:
这里既然提到了里氏替换原则,那接下来就给大家补充一下面向对象设计的七大设计原则(同时也是软考中级软件设计师中的一个考点):
- 单一职责原则:要设计目的单一的类;
- 开发——封闭原则:对扩展开发,对修改关闭;
- 里氏替换原则:子类可以替换父类;
- 依赖倒置原则:要依赖于抽象,而不是具体实现;针对接口编程,不要针对实现编程;
- 接口隔离原则:使用多个专门的接口比使用单一的总接口要好;
- 组合重用原则:要尽量使用组合,而不是继承关系来达到重用的目的(这样可以降低耦合度);
- 迪米特原则(最少知识法则):一个对象应当对其他对象有尽可能少的了解。