重载(Overload)
- 定义
在同一类中,方法名称相同,参数不同。(返回类型可以相同也可以不同)
- 为什么要重载?
灵活应用。如下图的list集合,可以在末尾添加内容,也可以在指定位置添加内容
重写(Override)
- 定义
指子类定义了一个与父类中具有相同名称、参数列表和返回类型的方法,并且子类方法的实现覆盖了父类方法的实现。即外壳不变,核心重写
- 重写的好处
子类可以根据需要,定义属于自己独特的行为。重写后,子类在调用该方法时,执行的是自己的方法,而不是父类的方法
(代码应用中可以提现)
区别
- 1、定义上有区别
- 重载:
重载是不同的函数使用相同的方法名,但是方法的参数个数或类型是不同的。调用时根据方法的参数来区别不同的方法
- 重写
是指在派生类中重新对父类中的虚函数重新实现,方法名和参数都一样,但是方法的实现体不一样
- 重载:
- 2、规则上不同(参数、修饰符、返回值)
- 重载:
1、必须有不同的参数列表(如类的无参构造方法和有参构造方法)
2、可以有不同的访问修饰符
3、可以抛出不同的异常 - 重写
1、重写的方法的参数列表与被重写方法的参数列表一致
2、重写的方法的返回类型与重写方法的返回类型一致
3、重写方法的访问修饰符大于被重写方法的访问修饰符
4、重写方法一定不能抛出新的检查异常,或者比被重写方法申明更加宽泛的检查型异常
5、声明为final的方法不能被重写
6、声明为static的方法不能被重写,但是可以再次声明
- 重载:
- 3、类关系上的区别
- 重载:
发生在同一个类中的方法之间,属于水平关系
- 重写
发生在子类和父类中,属于垂直关系
- 重载:
- 4、修饰符
重写有修饰符@override,重载没有
代码应用
public class Test {
public static void main(String[] args) {
/***
* Animal类中的方法:
* 1、被private修饰的defense()方法,该方法不可调用,不可重写
* 2、被protected和static修饰的bark()方法,该方法可以直接类调用,也可以创建对象调用
* 3、定义了一个final修饰的move()方法,该方法可以被调用,但允许重写
* 4、重写了一个move方法
* 5、定义了一个返回类型为Animal的run()方法,该方法被重写后,返回类型为Animal或者Animal类的派生类
*/
Animal animal = new Animal();
animal.run();
/***
* Dog类:继承了Animal类
* 1、重写了run()方法
* 2、重载了run()方法。根据传入的参数不同,可以调用不同的方法
* 3、可以直接调用父类中带有static修饰符的方法
*/
Dog dog = new Dog();
dog.run(5);
dog.move("Kandi");
//Dog.bark(); // 继承了Animal的带有static修饰符的
dog.bark();
/***
* Cat类:继承了Animal类
* 1、定义了一个自己的被final和static修饰的eat()方法
* 2、重写了eat()方法,同时重写的eat方法被static修饰
* 2、可以直接调用父类中带有static修饰符的方法
*/
Cat cat = new Cat();
cat.eat(5);
cat.run();
Cat.eat(5);
Cat.eat("ali");
cat.defense();
}
}
class Animal {
// 被private修饰的方法,类对象无法调用,同时也无法调用
// 被static修饰的方法,不能被重写,但是可以再被声明,再次声明时必须加static修饰符
public static void defense(){
System.out.println("Animal的防御行为");
}
// 被protect修饰的方法,继承后可以直接
protected void bark(){
System.out.println("动物在叫");
}
// 被final修饰的方法,不允许被重写
// final关键字对方法重载不起作用
public final void move(String s){
System.out.println("动物"+s+"在移动");
}
// 重载的move()方法
public void move(){
System.out.println("动物在移动");
}
// 普通的run()方法
public Animal run(){
System.out.println("Animal run...");
return new Animal();
}
}
class Dog extends Animal{
/***
* 1、Dog类继承了Animal的类,且重写了Animal的run()方法
* 2、重写的run()方法名称相同、参数列表相同
* 3、返回类型可以不同,但必须是父类返回值的派生类
*/
@Override
public Animal run() { // 可以返回Animal、Cat、Dog。因为Cat、Dog都是Animal的派生类
System.out.println("Dog is running...");
return new Cat(); // 这里涉及到了多态思想,也可以是 new Animal()。试着理解一下吧
}
/***
* 重写了run()方法:返回类型可以相同可以不同,但是
* 1、参数类型不同
* 2、参数个数不同
* 3、重写只对方法名称和参数做校验,如果方法名称和参数完全相同,返回值不同,也会报错
*/
public int run(int num,int num2){
System.out.println((num+num2)+"只狗在跑...");
return num+num2;
}
public void run(int num){
System.out.println(num+"只狗在跑...");
}
public void run(String name){
System.out.println("狗狗"+name+"在跑...");
}
}
class Cat extends Animal{
public static void defense(){
System.out.println("小猫防御");
}
/***
* 自定义的eat()方法
*/
public static final void eat(int num){
System.out.println(num+"只Cat在吃鱼");
}
public static void eat(String name){
System.out.println("小猫"+name+"在吃鱼");
}
}