在Java编程中,经常遇到向上与向下转型的问题,在此深入研究下。
向上转型,一句话:将父类的引用指向子类对象。
举例:在一个普通的家庭中,父亲的娱乐方式就是打开电视,收看京剧。唯一的儿子娱乐方式就多些,他既会打开电视收看生活大爆炸,又会上网。
编写代码如下:
class Father{
void watchTv(){
System.out.println("watching 京剧");
}
}
class Son extends Father{
@Override
void watchTv() {
// TODO Auto-generated method stub
System.out.println("watching 生活大爆炸");
}
void surfInternet(){
System.out.println("surfing Internet");
}
}
public class 向上转型 {
public static void main(String[] args) {
Father father = new Son();
father.watchTv();
// father.surInternet(); 不能实现,向上转型时,子类特有的方法丢失。
}
}
程序的输出结果是:watching 生活大爆炸,father也不能调用surfInternet方法。所以,父类的引用在这里动态绑定了子类的重写的方法,而子类特有的方法将丢失。
那么为什么会是这样呢,分析内存中的处理过程(VIP):
向上转型到底有什么用呢?
假如这位父亲有好3个儿子,每个儿子看电视时选择的节目不一样,第一个看生活大爆炸,第二个看中国好声音,第三个比较小,最喜欢看大风车。
编写代码如下:
<pre name="code" class="java">class Father{
void watchTv(){
System.out.println("watching 京剧");
}
}
class Son1 extends Father{
@Override
void watchTv() {
// TODO Auto-generated method stub
System.out.println("watching 生活大爆炸");
}
}
class Son2 extends Father{
@Override
void watchTv() {
// TODO Auto-generated method stub
System.out.println("watching 中国好声音");
}
}
class Son3 extends Father{
@Override
void watchTv() {
// TODO Auto-generated method stub
System.out.println("watching 大风车");
}
}
public class 向上转型 {
public static void main(String[] args) {
run(new Son1());
run(new Son2());
run(new Son3());
}
public static void run(Son1 son1){
son1.watchTv();
}
public static void run(Son2 son2){
son2.watchTv();
}
public static void run(Son3 son3){
son3.watchTv();
}
}
输出的结果是:
watching 生活大爆炸
watching 中国好声音
watching 大风车
可以看到,run()方法由于参数不统一,重载了三次,加大了编程量,降低了效率。
这时候只写一个run()方法,而参数改为Father father
public class 向上转型 {
public static void main(String[] args) {
run(new Son1());
run(new Son2());
run(new Son3());
}
public static void run(Father father){
father.watchTv();
}
}
输出结果也和上面一致,因为向上转型的存在,极大了方便了我们。
ctrlz presents!