一、JAVA重载和重写的区别
在JAVA中,重载(overload)和重写(override)是两个不同的概念。重载是指定义了多个同名的方法,但是参数的类型、个数或顺序不同,而重写是指子类覆盖了父类的同名方法。
重载方法在调用时会根据传入的参数类型、个数或顺序的不同,自动调用对应的方法。而重写方法则是在运行时根据实际对象的类型来决定调用哪个方法。
举个例子,假设我们有一个Animal类和它的子类Cat和Dog,Animal类中定义了一个名为speak的方法:
public class Animal { void speak() { System.out.println("动物叫声"); } } public class Cat extends Animal { void speak() { System.out.println("喵喵喵"); } } public class Dog extends Animal { void speak() { System.out.println("汪汪汪"); } }
在这个例子中,Animal中定义的speak方法是一个不带参数的方法。但是如果我们在Animal中再定义一个带参数的speak方法:
public class Animal { void speak() { System.out.println("动物叫声"); } void speak(String language) { System.out.println("使用" + language + "叫声"); } }
那么这个时候,我们在调用speak方法时就需要根据传入的参数来决定使用哪个speak方法:
Animal animal = new Animal(); Cat cat = new Cat(); Dog dog = new Dog(); animal.speak(); // 输出:动物叫声 animal.speak("英语"); // 输出:使用英语叫声 cat.speak(); // 输出:喵喵喵 cat.speak("英语"); // 输出:使用英语叫声 dog.speak(); // 输出:汪汪汪 dog.speak("英语"); // 输出:使用英语叫声
二、JAVA重载和重写
1. 参数类型
参数类型是重载方法和被重写方法最显著的不同点。对于重载方法,它们必须拥有不同的参数类型。而对于被重写方法,子类方法必须完全匹配其父类方法的参数类型。
public class Animal { void speak() { System.out.println("动物叫声"); } void eat() { System.out.println("动物吃东西"); } } public class Cat extends Animal { void speak() { System.out.println("喵喵喵"); } void eat(String food) { System.out.println("吃" + food); } } public class Dog extends Animal { void speak() { System.out.println("汪汪汪"); } void eat(String food) { System.out.println("吃" + food); } }
在这个例子中,Cat和Dog继承了Animal类,而Cat和Dog各自重写了eat方法,并且添加了一个字符串类型的参数。这时,我们在调用eat方法时,就需要传入一个字符串参数:
Animal animal = new Animal(); Cat cat = new Cat(); Dog dog = new Dog(); animal.eat(); // 编译错误:Animal类中没有eat()方法 cat.eat("鱼"); // 输出:吃鱼 dog.eat("骨头"); // 输出:吃骨头
2. 访问修饰符
访问修饰符也可以作为重载和重写方法的不同点之一。对于重载方法,它们可以有不同的访问修饰符。而对于被重写方法,子类方法不能缩小其父类方法的访问修饰符。
public class Animal { void speak() { System.out.println("动物叫声"); } private void run() { System.out.println("动物奔跑"); } } public class Cat extends Animal { public void speak() { System.out.println("喵喵喵"); } // 编译错误:不能缩小访问修饰符 // void run() { // System.out.println("猫跑步"); // } public void run() { System.out.println("猫跑步"); } } public class Dog extends Animal { public void speak() { System.out.println("汪汪汪"); } // 编译错误:不能缩小访问修饰符 // protected void run() { // System.out.println("狗跑步"); // } public void run() { System.out.println("狗跑步"); } }
在这个例子中,Animal中定义了一个私有的run方法。Cat和Dog继承了Animal类,并分别重写了run方法,并尝试缩小其访问修饰符。但是,由于父类中run方法的访问修饰符是私有的,所以子类方法将不能访问这个方法。
3. 返回类型
返回类型也可以作为重载和重写方法的不同点之一。对于重载方法,它们可以有不同的返回类型。而对于被重写方法,子类方法的返回类型必须与其父类方法相同,或是其父类方法返回类型的子类。
public class Animal { Object speak() { System.out.println("动物叫声"); return null; } } public class Cat extends Animal { // 编译错误:返回类型与父类不兼容 // int speak() { // System.out.println("喵喵喵"); // return 0; // } String speak() { System.out.println("喵喵喵"); return "喵喵喵"; } } public class Dog extends Animal { // 编译错误:返回类型与父类不兼容 // String speak() { // System.out.println("汪汪汪"); // return "汪汪汪"; // } Object speak() { System.out.println("汪汪汪"); return null; } }
在这个例子中,Animal中定义了一个返回类型为Object的speak方法。Cat和Dog继承了Animal类,并尝试重写speak方法,并尝试使用不同的返回类型。但是,由于子类方法的返回类型必须与父类方法相同,或是其父类方法返回类型的子类,所以子类的做法是错误的。
三、JAVA中方法重写和重载的区别
JAVA中方法重写和重载是两个概念,但是由于它们都与方法有关,所以容易混淆。方法重写是子类覆盖了父类的同名方法,方法重载是在同一个类中定义了多个同名的方法,但是参数的类型、个数或顺序不同。
方法重写有一个重要的特点:动态绑定。子类实例在运行时会根据实际对象的类型来决定调用哪个方法。而对于方法重载,会根据参数类型、个数或顺序的不同,自动调用对应的方法。
因此,方法重写是实现多态的一个重要手段。而方法重载则更多地用于提供多种便利的方法调用方式。在实际开发中,我们需要根据实际需要选择是使用方法重载还是方法重写。