public class Wine {
public void fun1(){
System.out.println("Wine 的Fun.....");
fun2();
}
public void fun2(){
System.out.println("Wine 的Fun2...");
}
}
public class JNC extends Wine{
/**
* 子类重载父类方法
* 父类中不存在该方法,向上转型后,父类是不能引用该方法的
*/
public void fun1(String a){
System.out.println("JNC 的 Fun1...");
fun2();
}
/**
* 子类重写父类方法
* 指向子类的父类引用调用fun2时,必定是调用该方法
*/
public void fun2(){
System.out.println("JNC 的Fun2...");
}
}
public class Test {
public static void main(String[] args) {
Wine a = new JNC();
a.fun1();
}
}
输出:
Wine 的Fun.....
JNC 的Fun2...
在这个程序中子类 JNC 重载了父类 Wine 的方法 fun1(),重写 fun2(),而且重载后的 fun1(String a) 与 fun1() 不是同一个方法,由于父类中没有该方法,向上转型后会丢失该方法,所以执行 JNC 的 Wine 类型引用是不能引用 fun1(String a) 方法。而子类 JNC 重写了 fun2() ,那么指向 JNC 的 Wine 引用会调用 JNC 中 fun2() 方法。
可以总结如下: 指向子类的父类引用由于向上转型了,它只能访问父类中拥有的方法和属性,而对于子类中存在而父类中不存在的方法,该引用是不能使用的,尽管是重载该方法。若子类重写了父类中的某些方法,在调用该些方法的时候,必定是使用子类中定义的这些方法。
// 通俗的想,父亲永远不可能转换成儿子。强转就出现了ClassCastException
Father f = new Father();
Son s = (Son)f;
/**
* Son 类特有的属性暂时不能通过 f 来操作,因为 Father 类没有 Son 类的特有属性
* 接着创建子类对象 s,它引用的是父类对象 f 强制转换来的对象,这时就可以通过 s 来操作子类的特有属性了
*/
Father f = new Son();
Son s = (Son)f;
/**
* 子类转换成父类,只是子类对象的特有属性无法利用 f 操作,f 可以操作其非特有的属性
* 也就是说,儿子可以执行吃饭和睡觉的方法,父亲也有,因为这就是从父亲继承的
* 但是让父亲执行上小学的方法就不行,因为这是儿子的‘特有属性’
*/
Son s = new Son();
Father f = (Father)s;
this 与 super
类在创建时,都会有一个默认的无参构造方法,它是子类 supe() 的默认通道,如果子类指定调用了父类的某个构造方法,super 就会往上追溯,如果没有指定,则默认调用 super(),如果父类没有提供默认的构造方法(默认的无参构造方法),子类继承时就会编译报错。
this 和 super 都是在实例化阶段调用,所以不能出现在静态方法或静态代码块中。this 的查找范围是先找本类,没有的话再去找父类,而 super 会直接寻找父类;