java引用变量有两个类型,一个是编译时类型,一个是运行时类型。
编译时由申明该变量时候使用的类型决定,比如Fruit duotai;
运行时由实际赋给该变量的对象决定,比如duotai=new Apple();
这就呈现了多态。
class Book { public String name="Book"; public void base() { System.out.println("书籍"); } public void open() { System.out.print("这是一本普通的书籍"); } } public class Java extends Book { public String name="Java"; public void open() { System.out.println("这是JAVA"); } public void go() { System.out.println("java方法"); } public static void main(String[] args) { Java book=new Java(); Java java=new Java(); java.open(); System.out.println("-------------------------------"); Book duotai=new Java(); //这里输出Book,表示访问的事父类的实例变量,并不是Java,原因是实例变量不具有多态性,实例方法具有多态性 System.out.println(duotai.name); //这是由父类继承来的base()方法 duotai.base(); //这是子类自己的方法 duotai.open(); //编译时是父类,没有子类方法,所以会出错 //duotai.go(); } } 这是JAVA ------------------------------- Book 书籍 这是JAVA
因为子类是个特殊的父类,所以可以把子类直接赋给父类引用变量,无需任何强制类型转换,被称之为向上转型,系统自动完成,引用变量
只能调用它编译时类型的方法,即使这对象确实包含运行时的方法。如果需要调用运行时方法,则需要把它强制转换成运行时的类型,需要借助类型转换运算符=》(type)variable
强制类型转换需要继承关系。
public class ConversionTest { Object ob="hellow";//编译时为Object,运行时为String,存在继承关系,可以强制类型转换 String obStr=(String)ob;//ob确实为子类实例,运行通过 Object object=new Integer(5);//存在继承关系 //但是运行类型为Integer,不是子类实例类型,所以不能强制转换, String str=(String)object;//失败,出现异常 //考虑到会出现异常,所以强制类型转换前通过Instanceof运算符来判断是否可以进行强制转换 public void InstanceTest() { if(object instanceof String) { String str=(String)object; } } }