- 重载:指在一个类中定义多个方法名相同但参数列表不同的方法
- “编译期绑定”,在编译时根据参数变量的类型判断应该调用哪个方法
- 重写:指在子类中定义中父类完全相同的方法
- “运行期绑定”,在运行时根据引用变量指向的实际对象类型调用方法
方法重写的返回值类型如果是基本类型 , 应与父类的返回值类型一致
public class Father {
static int b=7;
int a=5;
public void say(){
System.out.println("父亲say");
}
public void write(){
System.out.println("父亲write");
}
}
public class Son extends Father {
static int b=9;
int a=4;
public void say(){
System.out.println("儿子say");
}
public void play(){
System.out.println("儿子play");
}
public static void main(String[] args) {
Father father=new Son();
father.say();
father.write();
// father.play();
System.out.println(father.a);
System.out.println(father.b);
Son son=new Son();
System.out.println(son.a);
System.out.println(son.b);
}
}
- 右边如果是一个子类对象,左边是父类引用,那么会自动向上转型为父类对象,如果右边是一个父类对象,左边是一个父类引用,那么必须向下强制转型为子类对象。
- 这本质是一个动态绑定,也就是说在编译期间无法确定具体类型,只有在运行期间才能确定具体类型,这里左边可以是一个接口或者是父类对象,右边是他的具体实现类,这样提供不同的实现类以实现父类存在或者接口中存在的方法已达到多态的目的。
- 子类向父类是自动转型,父类向子类是需要强制转型,这和基本类型之间的运算很相似,一个小类型会自动转化为大类型,但是大类型像小类型转化就需要强制转化,转化过程中可能出现精度损失,这类似于小盒子可以轻松放入大盒子,但是大盒子放入小盒子却需要一定转换一样。
如果是父类引用指向子类对象这种形式,有以下几种情况:
- 如果子类重写了父类的某个方法,那么此时调用的是子类重写的方法
- 如果子类没有重写父类的某个方法,那么此时调用的是父类中的方法
- 如果子类新增了父类中不存在的方法,那么这个父类引用是不能调用这个仅在子类中存在的方法中,因为子类对象自动向上转型为了父类对象
- 如果子类与父类有同名的成员变量和静态变量,那么由于子类自动向上转型为父类对象,此时调用father.a,那么输出的必然是父类的成员变量和静态变量,这里不存在子类覆盖父类同名变量这一说,因为这里本身可以看做是一个父类对象
- 如果是Son son=new Son(),那么这就是实实在在的一个子类对象,那么son.a和son.b,这样就会覆盖父类的同名变量,输出的是子类的成员变量a和静态成员变量b,如果子类中没有同名变量,那么son.a和son.b调用的是父类的a和b。