java重载和重写
重载
我的理解:重载后的方法本质就是一个新的方法,访问修饰符返回值都是可以自行定制。他们的特性:方法名字相同。编译器为了区分重载方法,编译器便根据参数的不同来区分(即参数的类型和参数的顺序)。
意义:满足多态的特性(静态多态,即编译期间就能确定调用哪个函数)。方便根据传入参数的不同,处理成不同的结果,而且看起来调用的同一个方法。
public class Father {
public void chongzai(int a, String str) {
System.out.println(a + str);
}
// 参数顺序不同
public void chongzai(String str, int a) {
System.out.println(str + a);
}
// 修饰符,返回值完全就想一个新的方法一样
private static int chongzai(int a) {
System.out.println(a);
return a;
}
// 参数上存在继承关系时
public void print(Object obj) {
System.out.println("obj print");
}
public void print(String string) {
System.out.println("string print");
}
// 添加上此方法无法通过编译,String和StringBuffer没有任何关系,因此无法确认null和何种类型
// public void print(StringBuffer some) {
// System.out.println("StringBuffer print");
// }
public static void main(String[] args) {
int a = 1;
String str = "abc";
Father father = new Father();
father.chongzai(a, str);
father.chongzai(str, a);
chongzai(a);
// null可以是String,也可以是Object。但是String继承Object,所以确认参数为String更为精准
father.print(null);
}
}
结果
1abc
abc1
1
string print
问题:为什么重载不根据返回值进行判断?参考文章链接
我的回答:
1. 表达能力不够,例如:返回值为void的就无法参与重载;
2. 不易理解,(void f(){} 和 int f(){ return 1;})有时你并不关心方法的返回值,你想要的是方法调用的其他效果,调用f(),根本无法知道调用的是哪个;
重写
遵循规则:
1. 子类重写的方法,方法名、参数列表和返回值要和被重写的方法相同;
2. Java中规定,被子类重写的方法不能拥有比父类方法更加严格的访问权限;
3. 在继承过程中如果父类当中的方法抛出异常,那么在子类中重写父类的该方法时,也要抛出异常,而且抛出的异常不能多于父类中抛出的异常(可以等于父类中抛出的异常)。例如,父类的一个方法申明了一个检查异常IOException,在重写这个方法时就不能抛出Exception,只能抛出IOException及其子类;
为什么子类重写的方法不能拥有比父类方法更加严格的访问权限?参考文章链接
答:符合里氏代换原则【即所有引用基类(父类)的地方必须能透明地使用其子类的对象)】
如果子类重写的方法访问权限小于被重写的方法,父类向下转型成子类的时候,就可能因为访问权限无法调用方法。
访问修饰符
特别注意protected,同一个包中均可以访问(如同空着修饰符)
访问修饰符 | 同 一个类 | 同一个包 | 同一个包的子类 | 同一个包的非子类 |
---|---|---|---|---|
public | √ | √ | √ | √ |
protected | √ | √ | √ | ⊘ |
空着 | √ | √ | ⊘ | ⊘ |
private | √ | ⊘ | ⊘ | ⊘ |