上溯和下溯

注:文章内容由网络及相关书籍整理而来,如此只为共享知识,给予帮助。

先给出个例子,代码如下:
package  casting;
public   abstract   class  Animal {
     public   abstract   void  speak();
     public   void  eat(){
         // 闷头吃,不做额外的事情
    }
}
...............................................................
package  casting;
public   interface  DoorGod {
     void  guard();
}
..................................................................
package  casting;

public   class  Cat  extends  Animal {

     public   void  eat() {
         try  {
            Thread.sleep( 1000 );
        }  catch  (InterruptedException e) {
            e.printStackTrace();
        }
         super .eat();
    }

     public   void  speak() {
        System.out.println( " 喵喵 " );
    }

}
..................................................................
package  casting;

public   class  Dog  extends  Animal  implements  DoorGod{

     public   void  speak() {
        System.out.println( " 汪汪 " );
    }

     public   void  guard() {
            System.out.println( " 汪汪,汪汪... " );
    }
   
}
    其中Animal为基类,定义speak和eat方法,eat方法给出了空实现; DoorGod为门神接口,定义了 guard方法来守护家门; Cat为继承Animal的子类,这里假定猫有挑食的习惯,在eat中要耽搁点时间看看伙食;Dog也为继承Animal的子类,同时它实现了DoorGod接口来守护家门。

    先说说上溯造型(upcasting)。这个术语缘于继承关系图的传统画法:将基类至于顶部,而向下发展的就是派生类。根据上面的sample,我给出下面的一个小应用:
package casting;

public class Main {

    public static void upcasting(Animal animal){
        animal.speak();
        animal.eat();
    }
    public static void main(String[] args) {
        Animal dog1 = new Dog();//上溯发生的地方
        upcasting(dog1);
       
        Dog dog2 = new Dog();
        upcasting(dog2);
    }

}
    在上溯的过程中,子类Dog的接口变窄了,它本身的一些方法(如guard方法)就不可见了。如果你想使用子类Dog中存在而超类Animal中不存在的方法(animal.guard()),编译时就不能通过了。打个比方,你可以把大学生当作学生来用,让他上课、写作业,但不能要求他过四级。由此可见,上溯造型是安全的类型转换。

    然而,下溯造型就未必是安全的了。我们经常会做些强制类型转换的事情,有时我们也会无意间遇到 ClassCastException的转换异常(从这一点来说,我们应该多用范型来避免不安全的类型转换)。例如:
(1)package casting;                                               package casting;

public class Main {                                               public class Main {

public static void downcasting(Animal animal){               public static void downcasting(Animal animal){
     
       if(animal instanceof Cat){                                 Cat cat = (cat)animal
          Cat cat = (Cat)animal;                                     cat.speak();
          cat.speak();                                              
        }                                                            Dog dog = (Dog)animal;;//Main.java:10
        if(animal instanceof Dog){                                  dog.guard();
            Dog dog = (Dog)animal;
            dog.guard();                                             }                                  
        }
}
    public static void main(String[] args) {                      public static void main(String[]  args) {
          
        Animal cat = new Cat();                                     Cat cat = new Cat();
        downcasting(cat);                                            downcasting(cat);//Main.java:15
                                                                      
        Dog dog = new Dog();                                        Animal dog = new Dog();
        downcasting(dog);                                           downcasting(dog);                                                              
    }                                                                     }
}                                                                     }
    如果没有采取措施(上面使用的措施是instanceof)判断对象的类型,那么向下的强制转换就是不安全的。这种转换错误在编译时是不能检测出来的,只有在运行时才会抛出 ClassCastException异常,运行右侧源码时,得到如下异常。
 喵喵
Exception in thread "main" java.lang.ClassCastException: casting.Cat
 at casting.Main.downcasting(Main.java:10)
 at casting.Main.main(Main.java:15)

转载于:https://www.cnblogs.com/dabeng/archive/2008/05/11/1192514.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值