Java向上转型和向下转型的区别(附带实例)

Java向上转型和向下转型的区别(附带实例)

在 Java 程序中,对象的类型转换是指子类与父类之间的转换,主要包括如下两种:

向上转型:指从子类到父类的转换;

向下转型:指从父类到子类的转换。

Java向上转型

类的继承关系使子类具有父类的成员变量和成员方法,这意味着父类的成员可以在它的派生子类中使用,也就是说子类的对象也是父类的对象,子类对象既可以作为该子类的类型也可以作为父类的类型。

将一个子类对象的引用转换为它父类的引用,称为向上转型。向上转型的语法格式如下:

父类|接口 对象名 = new 子类();

举个简单的例子,Pet 是 Cat 的父类,参考代码如下:

Pet p = new Cat();

p.eat(); // 调用子类的eat()方法

向上转型体现的是“is a”关系。例如,一个 Cat 类的对象(猫)是一个 Pet 类(宠物)的对象,这是没有问题的,因为 Cat 类继承了 Pet 类的成员变量和成员方法,这意味着 Pet 类的对象 p 调用 eat() 方法时,可以完成相应的操作。

由于子类通常包含比父类更多的成员变量和成员方法,因此任何一个从父类派生出的各种子类都可以作为父类的类型对待。也就是说,从一个特殊的、具体的类型到一个通用、抽象类型的转换,肯定是安全的。

Java向下转型

向下转型也称为对象的强制类型转换,是指将父类对象类型的变量强制转换为子类类型。

向上转型使父类对象可以指向子类对象,但通过父类对象只能访问父类中定义的成员变量和成员方法,子类特有的部分成员被隐藏,不能被访问。只有将父类对象强制转换为具体的子类类型,才能访问子类的特有成员。

向下转型的语法格式如下:

子类 对象名 = (子类)父类对象;

参考代码如下:

Pet p = new Pet();

Dog d1 = new Dog();

Dog d2;

// d2 = (Dog)p; 这种写法转换失败,因为p指向的类型是Pet,d2的引用类型为Dog

// 下面的写法正确,首先将p的引用指向d2,此时的p的类型变成了Dog,所以同类型之间可以转换

p = d2;

d2 = (Dog)p;

向下转型可以调用子类类型中所有的成员,不过需要注意的是,如果父类引用对象指向的是子类对象,那么向下转型的过程是安全的,也就是编译时不会出错误。但是,如果父类引用对象是父类本身,那么向下转型的过程是不安全的,编译不会出错,但是运行时会出现 Java 强制类型转换异常。

针对这种情况,Java 语言中提供了 instanceof 关键字,可以先通过 instanceof 关键字来判断某个对象是否属于某种数据类型(类或接口),当前面的判断结果为 true 时再执行转换,其语法格式如下:

引用类型变量 instanceof 类名|接口

接下来,通过案例来演示向下转型:

class Pet { // 宠物类

private String name = "无名"; // 昵称

private int health = 100; // 健康值

public void eat() {}

}

class Dog extends Pet { // 狗类继承自宠物类

public void eat() { // 重写eat()方法

System.out.println("狗狗在啃骨头");

}

}

class Cat extends Pet { // 猫类继承自宠物类

public void eat() {

System.out.println("猫咪在吃鱼干");

}

}

class Master {

private String name; // 主人的姓名

public void feed(Pet p) { // 主人喂宠物,具体类型由传入的类型决定

p.eat();

}

}

public class Demo {

public static void main(String[] args) {

Pet p = new Dog(); // 向上转型

if (p instanceof Dog) { // 判断对象是否是Dog类型

Dog o = (Dog) p; // 向下转型

o.eat();

} else if (p instanceof Cat) { // 判断对象是否是Cat类型

Cat c = (Cat) p; // 向下转型

c.eat();

}

}

}

程序的运行结果如下:

狗狗在啃骨头

通过程序运行结果可发现,instanceof 能准确判断出对象是否是某个类的实例,有效地防止了运行时异常的发生,提高了程序的健壮性。

注意,在使用 instanceof 运算符时,该运算符前面的操作数的编译时类型要么与后面的类型相同,要么与后面的类型具有继承关系,否则会引起编译错误。

相关推荐

鞍山十大酒吧排行榜
365bet官方投注

鞍山十大酒吧排行榜

🪐 06-29 👁️ 9877
Oracle OCM考试全流程总结(具体步骤+个人建议)
365bet官方投注

Oracle OCM考试全流程总结(具体步骤+个人建议)

🪐 08-04 👁️ 9727
做膩好沒Fu? 床上激愛「7攻略」...別傻傻只用那幾招!