千锋教育-做有情怀、有良心、有品质的职业教育机构

400-811-9990
手机站
千锋教育

千锋学习站 | 随时随地免费学

千锋教育

扫一扫进入千锋手机站

领取全套视频
千锋教育

关注千锋学习站小程序
随时随地免费学习课程

上海
  • 北京
  • 郑州
  • 武汉
  • 成都
  • 西安
  • 沈阳
  • 广州
  • 南京
  • 深圳
  • 大连
  • 青岛
  • 杭州
  • 重庆
当前位置:太原千锋IT培训  >  技术干货  >  从零开始学Java之向上转型与向下转型

从零开始学Java之向上转型与向下转型

来源:千锋教育
发布人:qyf
时间: 2023-03-24 18:01:41

  面向对象的第三个特征是多态,实现多态有三个必要条件:继承、方法重写和向上转型。但是我们现在还不知道什么是向上转型,所以在学习多态之前,我们还要先学习Java的类型转换。本篇文章,就来带大家认识什么是类型转换,看看类型转换都有哪几种情况,以及如何避免类型转换时出现异常。

  一. 类型转型

  将一个类型转换成另一个类型的过程被称为类型转换。我们所说的对象类型转换,一般是指两个存在继承关系的对象,而不是任意类型的对象。如果两个类型之间没有继承关系,就不允许进行类型转换,否则会抛出强制类型转换异常(java.lang.ClassCastException)。

  Java语言允许某个类型的引用变量引用子类的实例,而且可以对这个引用变量进行类型转换。Java中引用类型之间的类型转换(前提是两个类是直接或间接的父子关系)主要有两种,分别是向上转型(upcasting)和向下转型(downcasting)。

  我们先来看下面这张图:

  猫、狗、牛、羊都是动物,所以”动物“是父类,猫狗牛羊是具体的子类。我们可以说猫是动物,狗是动物,牛是动物,羊是动物,这个结论肯定没错!但如果我们说,动物是猫,动物是狗,动物是牛,动物是羊,这个结论一定正确吗?那可就不一定了。子类肯定符合父类类型,但反之,父类不一定符合子类类型!

  接下来分别对向上转型和向下转型进行讲解。

  二. 向上转型

  概念

  所谓的向上转型,就是父类引用指向子类的对象,也就是把子类对象直接赋给父类引用变量,此时不用强制转换。比如我们说猫是动物,狗是动物,牛是动物,羊是动物,这就是把子类当成父类来用。父类是子类的上级,我们直接把子类向上提拔转型了。

  特点

  向上转型具有如下特点:

  ● 编译类型取决于=号左边,运行类型取决于=号右边;

  ● 子类可以调用父类的所有成员,但需遵守访问权限;

  ● 父类不能调用子类的特有成员;

  ● 最终的运行效果取决于子类的具体实现。

  语法

  向上转型的基本语法如下所示:

  //左侧是父类引用变量,右侧是创建的子类对象,我们可以把它当作父类使用

  父类类型 引用名 = new 子类类型();

  案例

  接下来我们通过一个案例来演示向上转型该如何实现。

  public class Cat implements Animal {

  @Override

  public void speak() {

  System.out.println("猫子:喵喵");

  }

  //给其他动物打招呼

  public void helloAnimal(Animal animal) {

  //向下转型,将父类型转为子类型。

  //此时有可能会出现ClassCastException类型转换异常,因为子类一定属于父类的一员,但父类不一定属于子类。

  //我们说“猫是动物”一定没问题,但如果说“动物是猫”,这个结论未必正确。所以把“动物强转成猫”的过程中,有可能会出现异常。

  //只有两者之间具有明确的父子关系时才能进行强转,否则就会出现类型转换异常。

  //向下转型时需要进行类型强转

  Cat cat=(Cat) animal;

  //向下转型后,可以使用子类Cat中的属性和方法。

  cat.speak();

  }

  }

  //测试类

  public class AnimalTest {

  public static void main(String[] args) {

  Animal animal=new Cat();

  animal.speak();

  Cat cat=new Cat();

  //这里我们传参时,既可以传递animal,也可以传递cat,但不能传递dog类型,否则会出现java.lang.ClassCastException:

  //因为class com.yyg.convert.Dog cannot be cast to class com.yyg.convert.Cat。狗不能被转成猫

  //cat2.helloAnimal(dog);

  cat.helloAnimal(animal);

  //Dog dog = new Dog();

  //这里就会编译出错,不允许把Dog对象类型转换成Cat对象类型

  //Cat cat = (Cat)dog;

  }

  }

  我们在进行向上转型时,可以写成Animal animal=new Cat(); Animal animal=cat;的形式。就是先创建出cat对象,然后再将cat对象赋值给Animal类型的变量,这样就实现了向上转型。因为Animal是父级类型,Cat是子级类型,Cat是Animal的子类,所以可以直接将cat变量赋值给animal,这就是向上转型。但这种写法比较繁琐,我们通常是直接采用Animal cat=new Cat();的形式,简洁明了。

  我们之所以可以实现向上转型,主要是因为两个类型之间是父子关系。比如在本例中,向上转型就等于说”猫是动物,狗是动物“,因为猫狗都是动物的子类,所以这个结论是确定无误的。

  三. 向下转型

  概念

  向下转型则反之,也就是一个已经向上转型的子类对象指向父类引用。向下转型后,可以调用子类类型中所有的成员。向下转型时,必须进行强制类型转换。因为父类拥有的成员,子类肯定会有,但子类拥有的成员,父类不一定有。

  但要注意,如果父类的引用对象指向的是子类对象,则向下转型时是安全的,即编译时不会出现错误。但如果父类的引用对象是父类本身,那么在向下转型的过程中是不安全的,虽然编译时不会出错,但在运行过程中会出现强制类型转换异常。我们可以使用instanceof运算符来避免出现强制类型转换异常。

  特点

  向下转型具有如下特点:

  ● 只能强制转换父类的引用,不能强制转换父类的对象;

  ● 父类的引用必须指向子类目标类型的对象;

  ● 向下转型后,父类可以调用子类类型中的所有成员。

  语法

  向下转型的基本语法如下所示:

  //向下转型使用强制类型转换的格式,将父类引用类型转换为子类引用类型

  子类类型 引用名 = (子类类型) 父类引用;

  案例

  接下来我们在上面的案例基础之上,对代码进行改造,在Cat类中增加一个新的方法。

  public class Cat implements Animal {

  @Override

  public void speak() {

  System.out.println("猫子:喵喵");

  }

  //给其他动物打招呼

  public void helloAnimal(Animal animal) {

  //向下转型,将父类型转为子类型。

  //此时有可能会出现ClassCastException类型转换异常,因为子类一定属于父类的一员,但父类不一定属于子类。

  //我们说“猫是动物”一定没问题,但如果说“动物是猫”,这个结论未必正确。所以把“动物强转成猫”的过程中,有可能会出现异常。

  //只有两者之间具有明确的父子关系时才能进行强转,否则就会出现类型转换异常。

  //向下转型时需要进行类型强转

  Cat cat=(Cat) animal;

  //向下转型后,可以使用子类Cat中的属性和方法。

  cat.speak();

  }

  }

  //测试类

  public class AnimalTest {

  public static void main(String[] args) {

  Animal animal=new Cat();

  animal.speak();

  Cat cat=new Cat();

  //这里我们传参时,既可以传递animal,也可以传递cat,但不能传递dog类型,否则会出现java.lang.ClassCastException:

  //因为class com.yyg.convert.Dog cannot be cast to class com.yyg.convert.Cat。狗不能被转成猫

  //cat2.helloAnimal(dog);

  cat.helloAnimal(animal);

  //Dog dog = new Dog();

  //这里就会编译出错,不允许把Dog对象类型转换成Cat对象类型

  //Cat cat = (Cat)dog;

  }

  }

  向下转型就是将父类型转为子类型,但要注意,此时有可能会出现ClassCastException类型转换异常,因为子类一定属于父类的一员,但父类不一定属于子类。我们说“猫是动物”一定没问题,但如果说“动物是猫”,这个结论未必正确。所以把“动物强转成猫”的过程中,有可能会出现异常。只有两者之间具有明确的父子关系时才能进行强转,否则就会出现类型转换异常。

  就比如上面的案例中,我们传参时,既可以传递animal,也可以传递cat,但不能传递dog类型,否则会出现java.lang.ClassCastException,因为class com.yyg.convert.Dog cannot be cast to class com.yyg.convert.Cat,狗类不能被转成猫类。

声明:本站稿件版权均属千锋教育所有,未经许可不得擅自转载。

猜你喜欢LIKE

React的遮羞布

2023-01-31

Local Storage的高阶用法

2023-01-31

javascript中如何将伪数组转换成真数组

2023-01-30

最新文章NEW

变量的预解析

2023-01-31

Vue中常见的组件间通信方案及典型应用场景

2023-01-31

VueJS中的动画菜单效果的实现

2023-01-31

相关推荐HOT

更多>>

快速通道 更多>>

最新开班信息 更多>>

网友热搜 更多>>