将一个类型强制转换成另一个类型的过程被称为类型转换。
本节所说的对象类型转换,是指存在继承关系的对象,不是任意类型的对象。当对不存在继承关系的对象进行强制类型转换时,会抛出 Java 强制类型转换(java.lang.ClassCastException)异常。
1.解释说明
假设,A类是B类的父类,当用子类创建一个对象,并把这个对象的引用放到父类的对象中时,比如:
A a;
a = new B();
或
A a;
B b = new B();
a = b;
这时,称对象a是对象b的上转型对象。
1.上转型对象不能操作子类新增的成员变量(失掉了这部分属性);不能调用子类新增的方法(失掉了一些功能)。
2.上转型对象可以访问子类继承或隐藏的成员变量,也可以调用子类继承的方法或子类的重写方法。上转型对象操作子类继承的方法或子类重写的方法,其作用等价于子类对象去调用这些方法。因此,如果子类重写了父类的某个方法后,当对象的上转型对象调用这个方法时一定是调用了子类重写的方法。
①不要将父类创建的对象和子类对象的上转型对象混淆。
②可以将对象的上转型对象再强制转换到一个子类对象,这时,该子类对象又具备了子类所有属性和功能。
③不可以将父类创建的对象的引用赋值给子类声明的对象
2.代码示例
2.1 示例一
public class Test {
static class Anthropoid{
double m=12.58;
void crySpeak(String s){
System.out.println(s);
}
}
static class People extends Anthropoid{
char m='A';
int n=60;
void compute(int a,int b){
int c=a+b;
System.out.println(a + "加" + b + "等于" + c);
}
@Override
void crySpeak(String s){
System.out.println(super.m + "**" + s + "**" + m);
}
}
public static void main(String[] args) {
People people=new People();
Anthropoid monkey=people;
monkey.crySpeak("A HAHA");
System.out.println(monkey.m);
System.out.println(people.m);
People zhang=(People) monkey;
zhang.compute(55,33);
zhang.m='Z';
System.out.println(zhang.m);
}
}
结果:
12.58**A HAHA**A
12.58
A
55加33等于88
Z
2.2 示例二
public class Test2 {
public static class Animal {
public String name = "Animal:动物";
public static String staticName = "Animal:可爱的动物";
public void eat() {
System.out.println("Animal:吃饭");
}
public static void staticEat() {
System.out.println("Animal:动物在吃饭");
}
}
public static class Cat extends Animal {
public String name = "Cat:猫";
public String str = "Cat:可爱的小猫";
public static String staticName = "Dog:我是喵星人";
@Override
public void eat() {
System.out.println("Cat:吃饭");
}
public static void staticEat() {
System.out.println("Cat:猫在吃饭");
}
public void eatMethod() {
System.out.println("Cat:猫喜欢吃鱼");
}
public static void main(String[] args) {
Animal animal = new Cat();
Cat cat = (Cat) animal;
System.out.println(animal.name);
System.out.println(animal.staticName);
animal.eat();
animal.staticEat();
System.out.println(cat.str);
cat.eatMethod();
}
}
}
结果:
Animal:动物
Animal:可爱的动物
Cat:吃饭
Animal:动物在吃饭
Cat:可爱的小猫
Cat:猫喜欢吃鱼
通过引用类型变量来访问所引用对象的属性和方法时,Java 虚拟机将采用以下绑定规则:
实例方法与引用变量实际引用的对象的方法进行绑定,这种绑定属于动态绑定,因为是在运行时由 Java 虚拟机动态决定的。例如,animal.eat() 是将 eat() 方法与 Cat 类绑定。
静态方法与引用变量所声明的类型的方法绑定,这种绑定属于静态绑定,因为是在编译阶段已经做了绑定。例如,animal.staticEat()是将 staticEat() 方法与 Animal 类进行绑定。
成员变量(包括静态变量和实例变量)与引用变量所声明的类型的成员变量绑定,这种绑定属于静态绑定,因为在编译阶段已经做了绑定。例如,animal.name和 animal.staticName 都是与 Animal 类进行绑定。
3. 强制对象类型转换
Java 编译器允许在具有直接或间接继承关系的类之间进行类型转换。
对于向下转型,必须进行强制类型转换;对于向上转型,不必使用强制类型转换。
例如,对于一个引用类型的变量,Java 编译器按照它声明的类型来处理。如果使用 animal 调用 str 和 eatMethod() 方法将会出错,如下:
animal.str = "";
animal.eatMethod();
如果要访问 Cat 类的成员,必须通过强制类型转换,如下:
((Cat)animal).str = "";
((Cat)animal).eatMethod();
把 Animal 对象类型强制转换为 Cat 对象类型,这时上面两句编译成功。对于如下语句,由于使用了强制类型转换,所以也会编译成功,例如:
Cat cat = (Cat)animal;
类型强制转换时想运行成功就必须保证父类引用指向的对象一定是该子类对象,最好使用 instanceof 运算符判断后,再强转,例如:
Animal animal = new Cat();
if (animal instanceof Cat) {
Cat cat = (Cat) animal;
...
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)