多态中的转型

转型

当父类的不能调用子类方法时,我们可以将父类转换成子类,然后就可以调用子类的方法。

转型分为两种:

向上转型:父类引用指向子类对象;

向下转型:父类引用转为子类对象;(强制转换)

转化的格式:

((目标类型)目标变量名).子类方法

我们从代码的形式上对转型进行了解:

class Animals{//父类
  public void play(){
      System.out.println("动物在玩");
}
}
class Cat extends Animals{//子类
    public void eat(){
        System.out.println("猫在吃鱼");
    }
}
public class Application{//测试类
    public class void main(String[] args){
        Animals a=new Cat();
        a.play();
        //a.eat();是调用不了的,多态形式中,方法的编译看左边,执行看右边;父类中没有eat这个方法,自然也就无法调用;
        //此时我们可以将a强制转换成Cat类型则可以进行调用eat方法;
        ((Cat)a).eat();
    }
}
//结果
猫在玩水
猫在吃鱼

引用类型的相互转换与基本类型转换的手法接近:向下转型则需要强制转换;向上转型则是自动转换;

这也就能解释为什么我们的cat对象可以直接变成Animals 类:Animals a=new Cat();

但是引用类型的转换是建立在两个类之间是有继承关系的,也可以说是建立在多态的形式上的!

但是低类型转换为高类型会失去低类型独有的的方法,就像基本数据类型由低到高转换会出现精度丢失的情况。

关于instanceof 的使用

instanceof 在Java语言中的功能是对两者之间是否有继承关系的判断。

我们在引用类型转换前可以通过instanceof来进行两者的判断

格式 : A(对象名) instanceof leiXing(待判断的引用类型)

instanceof的运行机制:

先判断是否能编译,然后再运行

先将A的引用类型与leiXing进行关系判断,若两者类型有继承关系则编译通过,然后再判断A是否为leiXing或者其子类的的实例对象。

让我们在代码中对instanceof 做进一步了解:

class Animals{//父类
  public void play(){
      System.out.println("动物在玩");
}
}
class Cat extends Animals{//子类
    public void play(){
        System.out.println("猫在玩水");
}
    public void eat(){
        System.out.println("猫在吃鱼");
    }
}
public class Application{//测试类
    public class void main(String[] args){
        Animals a=new Cat();
        System.out.println(a instanceof Cat);
        // a的引用类型为Animals,与Cat存在继承关系,编译通过;再判断对象a是否为Cat的实例对象,是,则整个判断下来为true;
        System.out.println(a instanceof Animals);
        // a的引用类型为Animals,编译通过;判断出a是 Animals子类Cat的实例,则整个判断下来为true;
        System.out.println(a instanceof Object);
        // a的引用类型为Animals,与Object存在继承关系,编译通过;判断出a是 Object子类Cat的实例,则整个判断下来为true;
        //System.out.println(a instanceof String);
        // a的引用类型为Animals,与String没有任何关系;编译不通过;
        
    }
}
//结果
true
true
true