向上转型、向下转型

来源:互联网 发布:有数据的新闻 编辑:程序博客网 时间:2024/05/02 13:44

逆变协变是在看lambda时提到通配符的时候看到的,感觉也是子类父类之间的关系,所以想和转型放在一起总结一下(协变逆变放另一篇)。


向上转型和向下转型

一句话:父类引用指向子类对象。(向上转型)

向上转型:子类引用的对象转换为父类类型称为向上转型。通俗地说就是是将子类对象转为父类对象。此处父类对象可以是接口

  • 该引用只能调用父类中定义的方法和变量;
  • 如果子类中重写了父类中的一个方法,那么在调用这个方法的时候,将会调用子类中的这个方法;(动态连接、动态调用)
  • 变量不能被重写(覆盖),”重写“的概念只针对方法,如果在子类中”重写“了父类中的变量,不会发生动态绑定(更确切的说,当子类没有重写方法,但调用的父类方法中所使用的参数在子类中也有,此时调用的仍是父类中的变量,而不是子类中的)。

向下转型:父类引用的对象转换为子类类型称为向下转型。


举个例子:有2个类,Father是父类,Son类继承自Father。

Father f1 = new Son();   // 这就叫 upcasting (向上转型)// 现在f1引用指向一个Son对象Son s1 = (Son)f1;   // 这就叫 downcasting (向下转型)

// 现在f1还是指向Son对象

第2个例子:

Father f2 = new Father();Son s2 = (Son)f2;       // 出错,子类引用不能指向父类对象

总结:

1.父类引用指向子类对象,而子类引用不能指向父类对象。

2.把子类对象直接赋给父类引用叫upcasting向上转型,向上转型不用强制转换。

  如:Father f1 = new Son();

3.把指向子类对象的父类引用赋给子类引用叫向下转型(downcasting),要强制转换。

如:f1 就是一个指向子类对象的父类引用。把f1赋给子类引用s1即 Son s1 = (Son)f1;

       其中f1前面的(Son)必须加上,进行强制转换。

向上转型时,父类指向子类引用对象会遗失除与父类对象共有的其他方法,也就是在转型过程中,子类的新有的方法都会遗失掉。

当子类重写了(override)父类的方法时,对象会调用子类的方法。

好处:

 public static void dosleep(Human h) {        h.sleep();    }

这里以父类为参数,调用时用子类作为参数,就是利用了向上转型。这样使代码变得简洁。不然的话,如果dosleep以子类对象为参数,则有多少个子类就需要写多少个函数。这也体现了JAVA的抽象编程思想。


向下转型:

Girl g1=new MMGirl(); //向上转型g1.smile();MMGirl mmg=(MMGirl)g1; //向下转型,编译和运行皆不会出错

这里的向下转型是安全的。因为g1指向的是子类对象。

Girl g2=new Girl();MMGirl mmg1=(MMGirl)g2; //不安全的向下转型,编译无错但会运行会出错

方法调用时的转型

```static Number method(Number num) {    return 1;}Object result = method(new Integer(2)); //correctNumber result = method(new Object()); //error,形参类型错误Integer result = method(new Integer(2)); //error,返回类型错误

“`

运行出错:
java.lang.ClassCastException:
如代码所示,可以通过instanceof来防止出现异常。(instanceof通过返回一个布尔值来指出,这个对象是否是这个特定类或者是它的子类的一个实例。)


逆变和协变