java基础回顾----多态

来源:互联网 发布:淘宝店招分层素材 编辑:程序博客网 时间:2024/05/18 00:39
package com.chapter_five;public class SubClass extends BaseClass{//重新定义book来隐藏父类变量public String book = "javaee开发";public void test(){System.out.println("子类的覆盖父类的方法");}public void sub(){System.out.println("子类的普通方法");}public static void main(String[] args){//多态测试BaseClass bs = new SubClass();System.out.println(bs.book);bs.test();<span style="font-family: Arial, Helvetica, sans-serif;">}   }</span>
class BaseClass{public int book = 6;public void base(){System.out.println("父类的普通方法");}public void test(){System.out.println("父类的被覆盖的方法");}}

最后的结果为:下图




第一部分

1.java引用变量有两种类型

编译时类型:由声明该变量是使用的类型决定

运行时类型:由实际付给该变量的对象决定

2.多态概念:

多态就是编译时类型和运行时类型不一致,就可能出现多态

上述代码中,BaseClass bs = new SubClass();这个bs引用变量的编译时类型是BaseClass,可运行时类型是SubClass,当运行时调用该引用变量的方法时,其方法行为总是表现出子类方法的行为特征,这就可能出现:相同的类型变量,调用同一个方法时呈现出不同的行为特征,这既是多态。

例如上述:当用BaseClass bs1 = new SubClass();和BaseClass bs2 = new BaseClass();,bs1和bs2都是BaseClass类型的引用变量,可是调用同一种方法的行为特征是不同的,也就形成了多态。

3.需要注意的问题:

<1>如果程序中加入

BaseClass bs = new SubClass();

bs.sub;//是错误的

程序会认为是错误的,因为bs编译类型是BaseClass类型,而sub方法是SubClass类中才有的,所以是无法调用此方法的。

<2>对于对象的实例变量来说,它不具备多态性,比如上述bs.book,最后结果是6,而不是子类隐藏后字符串的bs.book。他是subclass类的实例变量,不是subclass类的实例变量。

4.测试与总结:把上述的main函数改为如下代码测试一下:

public static void main(String[] args){//多态测试BaseClass bs = new SubClass();System.out.println(bs.book );bs.test();bs.base();//a可以,b不可以int test = bs.a;//int test1 = bs.b;错误//bs.sub();错误的,   //因为:java代码中,引用变量只能调用声明该变量是所用类里包含的方法(即可以调用编译时//类型所具备的的方法,但是如果想调用运行时类型所具备的方法呢?这就要用到引用变量的强制类型转换)SubClass sc = (SubClass)bs;sc.sub();}
总结:<1>.多态测试:(对于方法,引用变量在编译阶段只可以调用编译时类型多具有的方法,在运行时则执行运行时类型所具有的方法),说白了就是引用变量只能调用父类的所有方法,但是子类新增的方法是不可以调用的,对于子类重写的方法,调用或运行的是子类的结果。

   <2>.(对于实例变量)引用变量可以调用父类所有的实例变量,但是不可以调用子类的新增实例变量,如果调用子类和父类共有的实例变量book,则得出的结果还是父类的实例变量(也就是说对象的实例变量不具备多态性)。

第二部分

这时就出现一个问题,如果我想调用子类新增的方法该怎么办?

就出现了一个新的概念:引用类型的强制转换,如果想调用编译时类型没有的 方法,但运行时类型有的方法,就需要用的引用类型的强制转换。


强制类型转换需要注意的问题:

1.首先强制类型转换有三种:

(1)基本类型的强制类型转换,这里不再详细说明,请看本人这篇文章http://blog.csdn.net/sinat_28108651/article/details/49202127

(2)基本类型到其他类型的转换,这里我总结了一下基本类型变量、基本类型包装类对象、字符串之间的相互转化:

                                               

(3)引用类型之间的强制类型转换:首先引用类型之间的转换,只能在具有继承关系的两个类型之间进行转换。如果试图把父类实例转换成子类类型,则这个对象必须是子类实例才行。(编译时时父类类型,运行时是子类类型(多态))看代码:

public class ConversionTest{public static void main(String[] args){double d = 13.4;long l = (long)d;System.out.println(l);int in = 5;// 试图把一个数值类型的变量转换为boolean类型,下面代码编译出错// 编译时候会提示: 不可转换的类型// boolean b = (boolean)in;Object obj = "Hello";// obj变量的编译类型为Object,Object与String存在继承关系,可以强制类型转换// 而且obj变量实际上类型是String类型,所以运行时也可通过String objStr = (String)obj;System.out.println(objStr);// 定义一个objPri变量,编译类型为Object,实际类型为IntegerObject objPri = new Integer(5);// objPri变量的编译时类型为Object,objPri的运行时类型为Integer,Object与Integer存在继承关系// 可以强制类型转换,而objPri变量实际上类型是Integer类型,// 所以下面代码运行时引发ClassCastException异常String str = (String)objPri;}}


0 0