向上转型和向下转型其实是java中的一种多态,继承和实现都有自己的转型方式,他们大致相同,略微在向下转型有一些区别。我们一般称向上转型为瘦身,假如A是B的父类,此时 A a = new b();叫做向上转型,会丢失自己和父类不同的方法,而重写父类和自己都有的方法。使用a调用方法时,发现子类有的方法就调用子类,子类没有的调用父类。假如A是B的子类,此时 A a = new b();叫做向下转型,但是在这里会有异常发生,因为父类根本不知道到底谁继承了他,这个时候需要强转,而继承还有一个问题就是,必须要先向上转型才能向下转型。接口实现可以直接向下转型。
class Useful {
public void f() {
System.out.println("Useful:f()");
}
public void g() {
System.out.println("Useful:g()");
}
public void w() {
System.out.println("Useful:w()");
}
}
class MoreUseful extends Useful {
public void f() {
System.out.println("MoreUseful:f()");
}
public void g() {
System.out.println("MoreUseful:g()");
}
public void u() {
System.out.println("MoreUseful:u()");
}
public void v() {
System.out.println("MoreUseful:v()");
}
}
public class RTTI {
public static void main(String[] args) {
System.out.println("-----------------------------------------------向上转型-----------------------------------");
Useful[] x = {
new Useful(),
new MoreUseful(),
};
try {
x[0].f(); //0 是 Useful
x[1].g(); //1 是 MoreUseful 是 Useful 子类 向上转型 为 Useful 各自使用自己的方法 (重写了)
// 找不到方法u() // 向上转型的 MoreUseful 失去了自己特有的方法 u 是因为 父类 useful 没这个方法 --- 瘦身了
// x[1].u();
((MoreUseful) x[1]).u(); // 把 向上转型 成 useful 的 MoreUseful 强转为 MoreUseful 依然拥有自己原本定义的方法
x[1].w(); //子类中没有定义w方法 可以直接使用父类 的方法
// 总结:向上转型 瘦身, 转型为父类的人 失去了自己新增的方法 和父类 同名同参同返回值的方法 会重写,没有的方法继续用父类的-------------------------------
// Exception in thread "main" java.lang.ClassCastException: Useful cannot be cast to MoreUseful
// ((MoreUseful) x[0]).u(); //而本身 没有这些方法的 父类useful 强转 为子类MoreUseful 会报错
System.out.println("-----------------------------------------------向下转型-----------------------------------");
/*
MoreUseful[] y = {
new MoreUseful(), //0 是 MoreUseful
(MoreUseful) new Useful(), //1是 Useful 父类 向下转型为 子类 MoreUseful
//虽然 解析没有出错 都是当我们运行时发现 这里是会报错Useful 不能投射到 MoreUseful 的,
// 因为 父类转为 子类 并不能找到子类对应的方法 将会导致方法凭空消失报错,
// 所以需要向向上转型(成为父类) 再向下转型(变回子类) 即可达到“假增肥” 效果
};
y[0].g();
y[1].f();
*/
// 但是 如果 父类是接口 向上转型(瘦身)不变 向下转型 父类 即可 达到增肥效果 (变成 子类 也可以使用子类)
// 因为子类 实现了 接口 的 方法 ,使用它 就是像在 使用 自己一样
Useful useful = new MoreUseful(); //上转 --瘦身 没有了自己的方法 只有重写的 和父类的
useful.f();
useful.w();
MoreUseful moreUseful = (MoreUseful) useful; //下转 “假增肥” 表面看是 父类 变子类 其实是变回自己 //有的就重写 没有 用父类
moreUseful.f();
moreUseful.u();
moreUseful.g();
moreUseful.v();
moreUseful.w();
} catch (ClassCastException e) {
System.out.println(e);
}
}
}