前面了解了父类和子类的继承关系。子类是对父类的继承和扩展,父类是子类的抽象。如果在程序中实例化了一个子类对象,是否能将指向该子类对象引用的子类变量,显示转换为父类类型的变量呢?或者指向父类对象引用的父类变量,能不能显示转换为子类类型的变量呢?
案例1:实例化EBook对象,将指向Ebook对象引用的变量显示转换为 Product类型的变量,然后使用Product类型的变量分别调用父类和子类方法。验证子类类型变量转换为父类类型变量后的使用。
在PCoreUnit1项目book包内新建EBookTest1类,main方法代码如下:
public static void main(String[] args)
{
//实例化EBook对象
EBook ebook = new EBook("三国演义",21.2,"罗贯中","展现三国历史风云","PDF格式",310);
// 转换为Product类型
Product product = (Product)ebook;
// 调用outProduct()方法
product.outProduct();
}在main()方法中,声明了Ebook类型变量ebook,ebook指向实例化的EBook对象的引用。在main()方法中也声明了Product类型的变量product,然后使用显示转换将ebook强制转换为Product类型并赋值给product变量。
转换后的product变量虽然指向ebook对象的引用,但由于product变量类型是Product类型,因此product变量只能访问子类继承父类的成员变量和方法,无法访问子类自身的成员变量和方法。如果子类重写了父类的方法,会调用子类的方法。
程序执行结果如下图所示:
将子类类型显示转换为父类类型,这种转换称为“向上转型”。子类类型转换为父类类型后,不能访问子类新增加的成员变量和方法。例如,在上面的案例代码中,父类变量product虽然指向其子类的对象引用,但不能访问EBook类的formation和filesize属性。
既然子类类型可以转换为父类类型。那么,父类类型是否也能转换为子类类型?
案例2:实例化Product对象,将Product类型的变量显示转换为Ebook类型的变量。
在PCoreUnit1项目book包内新建EbookTest2类,main方法代码如下:
public static void main(String[] args)
{
// 实例化Product对象
Product product = new Product("三国演义",21.2,"罗贯中","展现三国历史风云");
// 转换为EBook类型
EBook ebook = (EBook)product;
// 输出图书名称
System.out.println(ebook.getName());
// 调用outProduct()方法
ebook.outProduct();
}程序执行结果如下图所示:

从程序执行结果可以看出,程序出错。因此父类类型变量指向父类对象引用时,该变量不能显示转换为子类类型变量。
如果父类类型变量指向子类对象引用时,可以使用显示转换将父类类型转换为子类类型,该转换称为“向下转型”。“向下转型”时,需要确保该父类类型变量指向的对象引用是子类的一个实例。
案例3:实例化EBook对象,将EBook对象的引用赋值给Product类型的变量,然后将该变量显示转换为Ebook类型的变量。
在PCoreUnit1项目book包内新建EbookTest3类,main方法代码如下:
public static void main(String[] args)
{
// 实例化Product对象
Product product = new EBook("三国演义",21.2,"罗贯中","展现三国历史风云","PDF格式",310);
// 判断product是否是EBook的实例
if( product instanceof EBook )
{
// 类型转换
EBook ebook = (EBook)product;
// 调用outProduct()方法
ebook.outProduct();
}
}在进行父类向子类的转换时,一个好的习惯是通过instanceof运算符来判断父类变量指向的对象引用是否是该子类的一个实例。