对象类型的转换在Java编程中经常遇到,主要分为向上转型和向下转型,但一定要记住,无论是向上转型还是向下转型,两个类之间必须有继承关系。先来看看基本概念。
向上转型又被称作自动类型转换,就是子类引用的对象转换为父类类型。通俗地说就是将子类对象转为父类对象。此处父类对象可以是接口。下面看代码来理解一下。
class Animal {
public void eat(){
System.out.println("animal eatting...");
}
}
class Cat extends Animal{
public void eat(){
System.out.println("猫吃鱼");
}
}
class Dog extends Animal{
public void eat(){
System.out.println("狗吃骨头");
}
public void run(){
System.out.println("狗会跑");
}
}
public class Main {
public static void main(String[] args) {
Animal animal = new Cat(); //向上转型
animal.eat();
animal = new Dog();
animal.eat();
}
}
输出:猫吃鱼
狗吃骨头
上述代码中将new出来的Cat类对象,Dog类的对象转换为Animal类的对象animal,实现的就是向上转型。向上转型的好处是减少重复代码,使代码变得简洁,并且可以提高系统扩展性。
但需要注意,向上转型时,子类单独定义的方法会丢失。比如上面Dog类中定义的run方法,当animal引用指向Dog类实例时是访问不到run方法的animal.run()会报错。
再来看向下转型。
//还是上面的animal和cat dog
Animal a = new Cat();
Cat c = ((Cat) a);
c.eat();
//输出 猫吃鱼
Dog d = ((Dog) a);
d.eat();
// 报错 : java.lang.ClassCastException:com.chengfan.animal.Cat cannot be cast to com.chengfan.animal.Dog
Animal a1 = new Animal();
Cat c1 = ((Cat) a1);
c1.eat();
// 报错 : java.lang.ClassCastException:com.chengfan.animal.Animal cannot be cast to com.chengfan.animal.Cat
为什么第一段代码不报错呢?因为a本身就是Cat对象,所以它理所当然的可以向下转型为Cat,也理所当然的不能转为Dog。而a1为Animal对象,它也不能被向下转型为任何子类对象。
向下转型需要注意哪些问题呢?
向下转型的前提是父类对象指向的是子类对象(也就是说,在向下转型之前,它得先向上转型)。
向下转型只能转型为本类对象(猫是不能变成狗的)。
向下转型之前需要养成一个良好的习惯,就是判断父类对象是否为子类对象的实例,这个判断通常用instanceof操作符来完成。可以参考以下的代码来理解instanceof操作符的用法。
public class GrandS extends Father{
public static void main(String[] args){
// a1是父亲对象的引用,a2是孙子类对象的引用
GrandF a1 = new Father();
GrandF a2 = new GrandS();
// 强制类型转换,不要看是对象的引用属于那个类,要看其引用的对象是否是将转换成的类的子类或‘本’类
Father b1 = (Father) a1;
Father b2 = (Father) a2; //相当于turn Grands to Father,子类转为父类,因为子类继承了父类,所以能够实现
//GrandS c1 = (GrandS) a1; //这个相当于是turn Father to GrandS,父类转为子类则不能够实现
GrandS c2 = (GrandS) a2;
// 通过instanceof函数来判断某一个对象的实际类型是否属于某一个指定类或派生于指定类的.
if(b1 instanceof GrandF) System.out.println("b1 belongs GrandF"); //b1为Father类,继承GrandF,true
if(b1 instanceof GrandS) System.out.println("b1 belongs GrandF");
else System.out.println("父类转为子类则不能够实现"); //父类转为子类不能够实现
if(a1 instanceof Father) System.out.println("a1 belongs Father"); //a1为Father类,true
if(a1 instanceof GrandS) System.out.println("a1 belongs GrandS"); //a1位Father类,不属于GrandS类,false
else System.out.println("a1 does not belong GrandS");
if(a2 instanceof GrandS) System.out.println("a2 belongs GrandS");
if(c2 instanceof GrandF) System.out.println("c2 belongs GrandF");
}
}
class Father extends GrandF {
}
class GrandF {
}
具体注释跟在代码的后面。使用instanceof操作符可以判断一个类是否实现了某个接口,也可以用来判断一个实例对象是否属于一个类。
好了,今天的内容就讲到这里。小编每天讲一个知识点,每天的知识点累积下来,将会是一个巨大的进步哦!如果觉得有用,欢迎转给身边的小伙伴!