什么是向上转型?
由导出类转型成基类,如"Human a1=new Woman( );"这就是一个向上转型。
什么是向下转型?
父类转型成子类就是向下转型,形如“Human a1=new Woman( );Woman b1=(Woman) a1;”。
为什么需要向上转型?
向上转型有两个好处,一个是我们不必知道正在处理的对象的确切类型,这一切都交给多态处理即可;另一个好处是可以简化代码数量。但是使用向上转型需要付出的代价是,不能使用子类中特有的类。先说说第一个优点及其缺点:
class China { public void language(){System.out.println("Chinese speak Chinese");} public void flu(){System.out.println("yellow");} } class HongKong extends China { public void language(){System.out.println("people lived in HongKong speak Chinese");} public void flu(){System.out.println("yellow");} public void location(){System.out.println("South of China");} } public class test1 { public static void main(String[] args) { China a1=new HongKong(); a1.language(); //a1.location(); } }输出结果:
如果把注释掉的a1.location()加上他会提示找不到loaction(),所以用不了子类新扩展的location()方法。那么你可能会有疑问,为什么不用HongKong al=new HongKong,直接调用location()方法呢?这样做其实就丧失了面向对象继承多态性的灵活。
接下来,讲一下节省代码是怎么一回事:
<pre name="code" class="java">//食材类 class Material { public void intro(){} } //盐类 class Salt extends Material { public void intro(){System.out.println("我是盐");} } //肉类 class Meat extends Material { public void intro(){System.out.println("我是肉");} } //蔬菜类 class Vegetable extends Material { public void intro(){System.out.println("我是蔬菜");} } public class MyMenu { public static void main(String[] args) { add(new Salt()); add(new Meat()); add(new Vegetable()); } public static void add(Salt m) { m.intro(); } public static void add(Meat m) { m.intro(); } public static void add(Vegetable m) { m.intro(); } }
此时如果用向上转型,MyMenu可以改为:
public class MyMenu { public static void main(String[] args) { add(new Salt()); add(new Meat()); add(new Vegetable()); } public static void add(Material m) { m.intro(); } }
向下转型有什么用?
用于父类调用子类方法或者父类给子类变量赋值,利于程序扩展。最多的应用是Java的泛型,但向下转型存在风险,如:
Human a2 = new Human(); Man b2 = (Man) a2;可能会出错:ClassCastException
这时可以用instanceof(判断是否是实例)来减少错误:
Human a2 = new Human(); if (a2 instanceof Man) { Man b2 = (Man) a2; b2.aMthod(); b2.bMethod1(); b2.bMethod2(); }