对象类型的转换在 Java 编程中会经常遇到,主要包括向上转型和向下转型操作。
1.向上转型
简单来讲的话就比如,因为平行四边形是特殊的四边形,也就是说平行四边形是四边形的一种,那么就可以将平行四边形对象看作是一个四边形对象。又例如,鸡是家禽的一种,而家禽又是动物中的一类,那么就可以将鸡对象看作是一个动物对象。所以,将子类对象看作是父类对象的行为,我们称为“向上转型”。由于向上转型是从一个较具体的类型到较抽象类型的一个转换,所以它总是安全的。
// 四边形类
public class Quadrangle {
public static void draw(Quadrangle quadrangle) {
// 四边形类中的方法
}
}
// 平行四边形类,继承四边形类
public class Parallelogram extends Quadrangle {
public static void main(String[] args) {
// 实例化平行四边形类对象的引用
Parallelogram parallelogram = new Parallelogram();
// 调用父类方法
draw(parallelogram);
}
}
如上所示,平行四边形继承了四边形类,四边形类中存在一个 draw() 方法,它的参数是 Quadrangle 类型,而在平行四边形类的主方法中调用 draw() 方法时给予的参数类型却是 Parallelogram 类型的。因为平行四边形也是四边形的一种特殊形式,所以可以将平行四边形类的对象看作是一个四边形类的对象,这就相当于“Quadrangle obj = new Parallelogram();”一样,就是把子类对象赋值给父类类型的变量,这种技术被称为“向上转型”。那基于此,其实正方形类、梯形类对象也可以作为 draw() 方法的参数,如果在四边形类的 draw() 方法中根据不同的图形对象设置不同的处理,就可以做到在父类中定义一个方法完成各个子类的功能,这样可以使同一份代码毫无差别地运用到不同类型之上,这就是多态机制的基本思想。
2.向下转型
通过向上转型其实可以推理出,向下转型是将较抽象的类转换为较具体的类。这样的转型通常会出现问题,例如,不能说四边形是平行四边形的一种。也就是说,子类对象总是父类对象的一个实例,但父类对象不一定是子类对象的实例。如果将上述代码示例中,将四边形类对象赋予平行四边形类对象,会发生什么呢?
// 平行四边形类,继承四边形类
public class Parallelogram extends Quadrangle {
public static void main(String[] args) {
draw(new Parallelogram());
// 将平行四边形对象看作是四边形类对象,称作向上转型
Quadrangle quadrangle = new Parallelogram();
// 将父类对象赋予子类对象,这种写法是错误的
Parallelogram parallelogram = quadrangle;
// 将父类对象赋予子类对象,并强制转换为子类型,这种写法是正确的
Parallelogram parallelogram1 = (Parallelogram) quadrangle;
}
}
很明显可以看到,代码中有报红片段。如果将父类对象直接赋予子类,会发生编译器错误,因为父类对象不一定是子类的实例。举例来说,四边形不一定就是平行四边形,还有可能会是梯形。其实,越是具体的对象,具有的特征就越多;越是抽象的对象,具有的特征就越少。在做向下转型的操作时,将特征范围小的对象转换为特征范围大的对象肯定会出问题,所以这时候就需要告知编译器这个四边形就是平行四边形。将父类对象强制转换为某个子类对象,这种方式称为显式类型转换。
在程序中使用向下转换技术时,必须使用显式类型转换,向编译器指明要将父类对象转换为哪一种类型的子类对象。