java引用变量有2个类型,一个是编译时类型,一个是运行时类型:
编译时类型:声明的类型,把它看做是什么东西
运行时类型:真正的类型,实际上指的是什么东西
如果编译时类型和运行时类型不同,就出现多态。相同类型的变量,调用同一个方法时呈现出多种不同的行为特征,这就是多态。
注意这个定义里面的关键字:方法。和方法不同,对象的属性不具备多态性。
编译时的类型由声明该变量时使用的类型决定,运行时的类型由实际赋给变量的对象决定。记住下面一句话就好:编译决定类型,运行绑定对象- 当一个引用类型的变量若声明为父类的类型,但实际上引用的是子类的对象(多态情况):
若子类覆写了父类的方法,那么此时通过变量访问到的方法,实际上是子类的方法;
- 实现多态的机制:
- 多态的作用:
继承是多态产生的前提条件:
编译时多态:方法重载
运行时多态:方法覆写 注意:静态方法不能被覆写!
- 引用变量类型转换
向下转型(父类→子类):(强制完成) 子类名称 子类对象 = (子类名称)父类实例 对象名 instanceof 类;
判断指定的变量名此时引用的真正类型是不是当前给出的类或子类;注意: 对象的类型和 类必须有继承关系。
在进行强制类型转换之前,先用instanceof运算符判断是否可以成功转换,从而避免出现ClassCastException异常,这样可以使程序更加健壮。
关于多态,代码如下:
/** * * @version 1L * @author LinkinPark * @since 2014-10-28 * @motto 梦似烟花心似水,同学少年不言情 * @desc ^多态的含义:编译决定类型,运行绑定对象,只是单纯的讲方法,和属性木有关系的 */ public class SubClass extends BaseClass{ public String name = "LinkinPark"; @Override public void test(){ System.out.println("当你的才华撑不起你的野心的时候,就该默默的学习了,,,"); } public void test2(){ System.out.println("面向对象,春暖花开,,,"); } public static void main(String[] args) { //以下2行运行时类型和编译时类型一致,不会发生多态 SubClass subClass = new SubClass(); BaseClass baseClass = new BaseClass(); //下面运行时类型和编译时类型不一致,发生多态 BaseClass linkin = new SubClass(); //多态是针对方法来说的,属性不具备多态性,所以编译时是什么类型,就调用那个类型的属性值 System.out.println(linkin.name); //子类的方法覆盖父类方法,调用子类方法 linkin.test(); //子类中不存在这个方法,那么只能调用父类的了 linkin.test1(); //尽管运行时类型是子类,但是编译的时候仍然不能调用子类的方法,除非向下强转 //linkin.test2(); //养成良好的习惯,在强制类型转换时候都要instanceof下判断下类型 if(linkin instanceof SubClass){ ((SubClass)linkin).test2(); } } } class BaseClass{ public String name = "Binger"; public void test(){ System.out.println("你以为你以为的真是就是你以为的么???"); } public void test1(){ System.out.println("梦想终究还是要有的,万一实现了呢,,,"); } }