1. Overide,重写
重写一般是发生在子类继承父类后,某些父类方法不适应子类的需求,而此时子类就重写相同的方法,更加自己的需求,定义自己特定的行为。
简单列子
public class Person {
String name;
int age;
public Person(String name, int age) {
this.name = name;
this.age = age;
}
public void say() {
System.out.print("my name is "+name+"," + age + " years old this year");
}
}
public class Teacher extends Person{
public Teacher(String name, int age) {
super(name, age);
}
@Override
public void say() {
System.out.print("my name is " + super.name+"," + age + " years old this year," + "i'm a teacher");
}
}
子类Teacher继承父类Person,并重写了say,重写的时候,编译器会帮你添加注解:override
。
1.1 输入参数宽度
重载对输入参数的宽度有限制,要求其必须等于父类的宽带。对于上面的例子,对Person增加一个方法:
/**
* 一下子吃超级多的东西
* 键值对:
* key - 食物名称
* value - 食物数量
* @param map map
*/
public void eat(Map map) {
Iterator iterator = map.keySet().iterator();
while (iterator.hasNext()) {
String key = iterator.next();
System.out.println("eat " + key + ", " + map.get(key));
}
}
当我们尝试子类重载方法,并使其输入参数小于父类的输出参数(HashMap是Map的一个子集),编译器提示报错
若此时我们把Override
去掉会发生什么?编译通过,但当传入Map的对象时候,会直接调用父类方法,而当传入HashMap对象的时候,编译器报错,提示,子类和父类皆有同名方法而参数类型也符合要球。当我们把子类的方法改改:
public void eat(int a) {
System.out.print("Teacher, eat");
}
是可以成功,且成功调用。
1.2 抛出异常宽度
重载对异常的抛出宽度有限制吗?还是同一个方法,父类定义:
/**
* 一下子吃超级多的东西
* 键值对:
* key - 食物名称
* value - 食物数量
* @param map map
*/
public void eat(Map map) throws IOException{
Iterator iterator = map.keySet().iterator();
while (iterator.hasNext()) {
String key = iterator.next();
System.out.println("eat " + key + ", " + map.get(key));
}
}
抛出一个异常IOException
,如果子类重载,抛出大于父类的异常Exception
:
编译器报错。那如果宽度小于父类的异常呢?
public class MyIOException extends IOException{
//定义一个继承IOException的异常
}
@Override
public void eat(Map map) throws MyIOException {
try {
super.eat(map);
} catch (IOException e) {
e.printStackTrace();
}
}
或者删除异常
@Override
public void eat(Map map) {
try {
super.eat(map);
} catch (IOException e) {
e.printStackTrace();
}
}
编译,运行成功。不过如果想要调用super.eat(map)
,因为其有抛出的异常,且宽度大于子类方法的MyIOException
,所以需要先捕抓异常。
1.3 返回类型
跟输入类型一样,必须一致,不能修改。
1.4 方法访问权限
一定不能做更严格的限制(可以降低限制),假如父类的方法声明为protected
,则,子类可以重载其为public
但不能为private
。
2. Overload,重载
重载发生在同一个类里面,名字相同,但是参数一定不同,返回值类型可以相同也可以不同。最常用到的是构造函数。来看一些例子:
//1
protected void eat(Map map) throws IOException{
System.out.println("eat Map");
}
//2
public void eat(HashMap map) {
System.out.println("eat HashMap");
}
//3
public void eat() {
System.out.println("eat null");
}
//4
public boolean eat(int a) {
System.out.println("eat a");
return true;
}
- 方法的参数一定要不同,在次前提下,其他的随意
- 方法返回值可以随意变化
- 方法的抛出异常也是
- 方法的访问权限也是
3. 总结
参考
区别点 | 重写(Override) | 重载(Overload) |
---|---|---|
参数 | 一定不能修改 | 必须不同 |
返回值 | 一定不能修改 | 随意 |
抛出的异常 | 可以减少,删除,不能抛出宽度更大的异常 | 随意 |
访问权限 | 不能做更严格的限制 | 随意 |
方法重载是一个类中定义了多个方法名相同,而他们的参数的数量不同或数量相同而类型和次序不同,则称为方法的重载(Overloading)。
方法重写是在子类存在方法与父类的方法的名字相同,而且参数的个数与类型一样,返回值也一样的方法,就称为重写(Overriding)。
方法重载是一个类的多态性表现,而方法重写是子类与父类的一种多态性表现。