Java中的函数重载和重写是什么意思?有何区别?
Java中的函数重载和重写都是面向对象编程中非常重要的概念,它们都是实现多态性的手段。但是它们的实现方式和应用场景略有不同,下面我们分别来介绍一下。
函数重载
函数重载指的是在同一个类中定义多个同名的函数,但是这些同名函数的参数列表不同,包括参数的类型、个数或者顺序等。函数重载一般来说不会改变函数的返回值类型,而是通过不同的参数列表来实现同一个函数的不同功能,提高了代码的复用性和扩展性。
例如,在一个计算器的类中,我们可以定义多个加法函数,分别接受两个整型参数、两个双精度浮点型参数、两个字符串等参数:
public class Calculator {
public int add(int a, int b){
return a + b;
}
public double add(double a, double b){
return a + b;
}
public String add(String a, String b){
return a + " " + b;
}
}
在使用时,根据需要选择不同的函数即可:
Calculator calculator = new Calculator();
int result1 = calculator.add(1, 2); // result1 = 3
double result2 = calculator.add(1.0, 2.0); // result2 = 3.0
String result3 = calculator.add("Hello", "World"); // result3 = "Hello World"
可以看到,通过函数重载,我们可以定义出同名的加法函数,分别适用于整型、双精度浮点型和字符串类型的加法运算。
函数重写
函数重写指的是子类重新定义了父类中已经存在的函数,同时函数的名称、参数列表和返回值必须保持一致。子类的函数重写必须满足一定的规则,例如访问修饰符不能低于父类中对应函数的访问修饰符、函数抛出的异常不能超过父类中对应函数抛出的异常、返回类型必须是父类对应函数返回类型的子类等等。
函数重写是实现多态的一种方法,它可以让不同的子类实现对同一个函数的不同实现,从而达到不同的功能。函数重写发生在继承关系中,且子类必须通过 super 关键字调用父类对应的函数,否则就会引发无限递归调用的错误。
例如,定义一个动物类和其子类狗类,其中动物类中有一个发声的 makeSound 函数,在子类中实现它们自己的叫声:
public class Animal {
public void makeSound(){
System.out.println("This is an Animal.");
}
}
public class Dog extends Animal {
public void makeSound(){
System.out.println("The Dog barks.");
}
}
在使用时,我们可以通过动态绑定的方式来调用子类的函数:
Animal animal = new Animal(); animal.makeSound(); // 输出:"This is an Animal." Dog dog = new Dog(); dog.makeSound(); // 输出:"The Dog barks."
通过函数重写,子类可以覆盖父类中的函数实现,提供更加具体的功能。
函数重载和函数重写的区别
虽然函数重载和函数重写都可以让同一个函数提供不同的功能,但它们在实现方式和应用场景上有一些区别。
1. 实现方式不同。函数重载是在同一个类中定义同名函数,参数列表不同;函数重写则是子类重新定义父类函数,函数名称和参数列表必须保持一致。
2. 作用不同。函数重载主要目的是提高代码的可读性和复用性,通过使用同名的函数提供不同的功能,简化代码的编写;函数重写主要是实现多态性,让父类中已有的函数只能被子类一一覆盖,实现不同的功能。
3. 范围不同。函数重载发生在一个类中,函数名和参数列表必须相同,但是返回值可以不同;函数重写发生在继承关系中,子类重写父类函数时必须保持函数名和参数列表相同,返回值必须是父类函数返回值的子类。
4. 用途不同。函数重载的主要作用是提高代码的可读性和复用性,让一个函数提供多种调用方式和实现方式;函数重写的主要目的是实现多态性,让子类能够实现自己的逻辑,同时保持和父类接口的一致性。
