今天下午小龙在练习instanceof用法时突然想到java的upcating 和 downcasting 好像与此有关联,于是自己写了一个相关的案例,在此与众位看到的亲们分享一下,希望能帮到正在学习的伙伴们。
package com.instanceoftest;
/** java向上转型和向下转型,以及用instanceof方法来防止向下转型错误
* 接口说明
*interface方式的实现中,Demo只能够有静态的不能被修改的数据成员(也就是必须是static final 的,不过在interface中一般不定义数据成员),
*所有的成员方法都是abstract的。从某种意义上说,interface是一种特殊形式的 abstract class。
*
* @author mengfl
*
*/
interface Animal{
public static final String color = "blue";
//abstract void voice();
abstract void eat();
}
class FlyAnimal implements Animal{
public void eat() {
// TODO Auto-generated method stub
System.out.println("父类 FlyAnimal eat worm!");
}
public void voice() {
// TODO Auto-generated method stub
System.out.println("父类 FlyAnimal sing wonderful!");
}
}
/*
* 继承接口
*/
class Parrot extends FlyAnimal {
@Override
public void eat() {
// TODO Auto-generated method stub
System.out.println("parrot eat worm!");
}
@Override
public void voice() {
// TODO Auto-generated method stub
System.out.println("parrot sing wonderful!");
}
public void jump(){
System.out.println("parrot can jump!");
}
}
class Instanceoftest {
public static void main(String[] args){
Animal a1 = new Parrot();
//a1.eat();//向上转型,只能调用父类Animal中的eat()方法
FlyAnimal a2 = new Parrot();//向上转型
// a2.eat();
// a2.voice();//向上转型,只能调用父类FlyAnimal中的eat()和voice()方法。
// 在向下转型过程中,分为两种情况:
//
// 情况一:如果父类引用的对象如果引用的是指向的子类对象,那么在向下转型的过程中是安全的。也就是编译是不会出错误的。
//
// 情况二:如果父类引用的对象是父类本身,那么在向下转型的过程中是不安全的,编译不会出错,但是运行时会出现java.lang.ClassCastException错误。它可以使用instanceof来避免出错此类错误。实例如下:
Parrot a3 = (Parrot)a2;// 安全的向下转型,编译和运行皆不会出错。注意这是建立在向上转型的基础上的
// a3.eat();
// a3.voice();
// a3.jump();
FlyAnimal a4 = new FlyAnimal();
//运行到下面的 Parrot a5 = (Parrot)a4 方法时,报以下异常
//Exception in thread "main" java.lang.ClassCastException: com.instanceoftest.FlyAnimal cannot be cast to com.instanceoftest.Parrot
// Parrot a5 = (Parrot)a4; //不安全的向下转型,编译无错但会运行会出错
// a5.eat();
// a5.voice();
// a5.jump();
if(a4 instanceof Parrot){
Parrot a5 = (Parrot)a4;
a5.eat();
a5.voice();
a5.jump();
}
}
}
//总结
//1、父类引用可以指向子类对象,子类引用不能指向父类对象。
//例如:FlyAnimal flyAnimal = new Parrot(); 可以
// Parrot a7 = new FlyAnimal();不可以
//2、把子类对象直接赋给父类引用叫upcasting向上转型,向上转型不用强制转型。
//
// 如Father father = new Son();//向上转型
//3、把指向子类对象的父类引用赋给子类引用叫向下转型(downcasting),要强制转型。
//在 FlyAnimal flyAnimal = new Parrot()中,如flyAnimal就是一个指向子类对象的父类引用
//,把flyAnimal赋给子类引用Parrot 即Parrot parrot =(Parrot)flyAnimal;
//4、upcasting 会丢失子类特有的方法,但是子类overriding 父类的方法,子类方法有效。