Java上溯造型(upcasting)与下溯造型(Downcasting)

上溯造型(upcasting)

这个术语缘于继承关系图的传统画法:将基类至于顶部,而向下发展的就是派生类。

文章使用的完整代码如下


public class Main {public static void main(String[] args) {Dog dog=new Dog();upcasting(dog);//汪汪汪。。。dog.tail();//摇尾巴...dog.speak();//汪汪汪。。。Animal animal=new Dog();animal.speak();//汪汪汪。。。
//      animal.tail();//The method tail() is undefined for the type Animal//下溯Dog d =(Dog)animal;d.tail();//错误的下溯
//      Animal a2=new Animal();
//      Dog d2=(Dog)a2;
//      d2.tail();
//      运行时报错:Exception in thread "main" java.lang.ClassCastException: class shangsu.Animal cannot be cast to class shangsu.Dog (shangsu.Animal and shangsu.Dog are in unnamed module of loader 'app')
//      at shangsu.Main.main(Main.java:16)  }public static void upcasting(Animal animal){  animal.speak();
//        animal.tail();//编译错误:The method tail() is undefined for the type Animalreturn;}  }class Animal {public void speak(){//      System.out.println("阿巴阿巴。。。");}
}class Dog extends Animal{@Overridepublic void speak() {System.out.println("汪汪汪。。。");}public void tail(){System.out.println("摇尾巴...");}}

由于upcasting(Animal animal)方法的参数是 Animal类型的,因此如果传入的参数是Animal的子类,传入的参数就会被转换成父类Animal类型,这样你创建的 Dog对象 能使用的方法只是Animal中的签名方法;也就是说,在上溯的过程中,Dog的接口变窄了,它本身的一些方法(例如tail方法)就不可见

如果你 想使用Dog中存在而Animal中不存在的方法 (比如tail方法),编译时不能通过。由此可见,上溯造型是安全的类型转换。另一方面,虽然upcasting(Animal animal)方法的参数是 Animal类型,但传入的参数可以是 Animal的派生类 (这也是OO编程中惯用的编程方法),这里面就有个对象的类型识别问题,也就是运行时类型识别(run-time type identification,缩写为RTTI) 。RTTI的功能主要是由Class类实现的。

简单来说,上溯造型就是把子类向上转换为父类类型Animal animal=new Dog();,这样转型后只能使用父类中已经声明过的方法(叫)而不能通过转换后的父类调用子类特有的方法(摇尾巴)

下溯造型(Downcasting)

不一定安全,在编译时检测不到,运行时会抛出ClassCastException异常,对于测试来说,这样的错误也是很难检测的。

  • 将父类对象显示的转换成子类类型。
  • 曾经向上转换过的对象,才能再向下转换。对象不允许不经过上溯造型而直接下溯造型。
Animal animal=new Dog();
Dog d =(Dog)animal;
d.tail();

不正确的下溯示例:

Animal a2=new Animal();//动物类对象a2
Dog d2=(Dog)a2;//下溯为Dog类对象
d2.tail();
//编译时无错误

运行时报错Exception in thread "main" java.lang.ClassCastException: class shangsu.Animal cannot be cast to class shangsu.Dog (shangsu.Animal and shangsu.Dog are in unnamed module of loader 'app') at shangsu.Main.main(Main.java:16)

正确示例:

public static void downcasting(Animal animal){if(animal instanceof Dog){Dog dog=(Dog)animal;dog.speak();dog.tail();}
}

Java类中重写equals()用到的下溯造型

(2021.9.15更新)

Q:为什么要重写equals() ?

A:引用类型比较,要使用equals()方法,如果使用==比较,它比较的是两个引用类型的变量是否是同一个对象。

同时,调用List的contains() indexOf()方法 都需要实现equals()方法

对于自己创造的一个类,本身并没有重写equals()方法,如果需要比较两个类实例是否相等 就必须要重写(调用List的contains() indexOf()方法 也需要重写)

在廖雪峰老师的JAVA教程的一个练习中就有重写equals()的练习,在编写时,我发现这个就是下溯造型,于是在这里写出。

class Person {String firstName;String lastName;int age;
public Person(String firstName, String lastName, int age) {this.firstName = firstName;this.lastName = lastName;this.age = age;
}/*** TODO: 覆写equals方法*/
@Override
public boolean equals(Object o) {if(this == o) {return true;}if(o instanceof Person) {Person pp=(Person)o;if(this.firstName.equals(pp.firstName) && this.lastName.equals(pp.lastName) &&this.age==pp.age) {return true;}}return false;
}

重写后即可完成main函数中的测试

public class Main {public static void main(String[] args) {List<Person> list = List.of(new Person("Xiao", "Ming", 18), new Person("Xiao", "Hong", 25),new Person("Bob", "Smith", 20));boolean exist = list.contains(new Person("Bob", "Smith", 20));System.out.println(exist ? "测试成功!" : "测试失败!");}
}

[Java初学]Java上溯造型(upcasting)与下溯造型(Downcasting)相关推荐

  1. 上溯造型、下溯造型的理解

    (上溯造型定义:java允许把一个子类对象直接复制给一个父类引用变量,自动完成类型转换,这种语法现象称为上溯造型. 下溯造型回到它自己所在的类(强制转换):一个对象被溯型为父类或接口后还可以再被下溯造 ...

  2. Java——上溯造型下溯造型

    public abstract class Animal {public abstract void speak();public void eat(){// 吃吃吃!!! } } public in ...

  3. Java 的上溯造型和下溯造型以及举例,以及判断参数等指向的类

    (一) 先给出个例子,代码如下: /** * @author WangQun * 动物抽象类 */ abstract class Animal { public abstract void speak ...

  4. java 下溯造型_Java——上溯造型下溯造型

    public abstract class Animal { public abstract void speak(); public void eat(){ // 吃吃吃!!! } } public ...

  5. java 下溯造型_Java 的上溯造型和下溯造型以及举例,以及判断参数等指向的类

    (一) 先给出个例子,代码如下: /** * @author WangQun * 动物抽象类 */ abstract class Animal { public abstract void speak ...

  6. java上溯造型与下溯造型

    Java的多态性 面向对象编程有三个特征,即封装.继承和多态. 封装隐藏了类的内部实现机制,从而可以在不影响使用者的前提下改变类的内部结构,同时保护了数据. 继承是为了重用父类代码,同时为实现多态性作 ...

  7. 学习上溯造型和下溯造型 【转载一篇】

    题按:做了几年的java程序,却很难说对基本的OO概念都有理解.即便每天都写的代码中,也很难说清楚其中到底运用了怎样的概念和思想.前日的考试中看到关于上溯造型与下溯造型的问题,就查了些资料,集中说一下 ...

  8. 上溯造型和下溯造性(解耦合)

    上溯造型: 向上转型(Upcasting)- 子类转换为父类,自动转换: 前提 - 具有继承或实现关系: 向上转换损失了子类新扩展的属性和方法,仅可以使用从父类中继承的属性和方法 Animal a=n ...

  9. Java的上溯、下溯

    2019独角兽企业重金招聘Python工程师标准>>> 抽象方法:只有方法声明没有实现,有一个抽象方法的的类叫抽象类 修饰符: 例: abstract class Operator{ ...

最新文章

  1. SD卡中FAT32文件格式快速入门(图文详细介绍)
  2. Git篇——Git使用教程
  3. 面试官:Spring事务的传播行为有几种?
  4. 5、线程终止方式:pthread_cleanup_push/pthread_cleanup_pop()
  5. linux查询字段排序,Linux 操作命令 sort
  6. 关于strlwr,strupr等函数在此作用域中尚未声明的问题
  7. python集合类型变量_Python小白学习之路(八)—【变量】【基本数据类型分类】【集合】【集合的功能】...
  8. linux下怎么编译动态库并且调用
  9. 单边指数信号的特点_今日股市分析:上证指数若能守住3400,蓄力反弹就有戏...
  10. Android中CursorLoader的使用、原理及注意事项
  11. asp.net 页面右下角弹出类似QQ或MSN的消息提示
  12. 实习成长之路:操作系统——CPU有哪些工作模式呢?
  13. java计算机毕业设计计算机组成原理教学网站MyBatis+系统+LW文档+源码+调试部署
  14. 如何提升自己写代码的能力
  15. 盘扣架市场持续低迷,春节后是否能“破圈”?
  16. 初学者笔记:Scanf间隔符号的使用
  17. kali中rarcrack爆破rar压缩包密码
  18. 全网比较火的爱心代码
  19. 音视频开发系列1:音视频开发基本概念
  20. k3595参数_1高频三极管的一些型号及参数

热门文章

  1. 基于知识图谱和推荐系统的统一药物靶点相互作用预测框架
  2. 快速原型工具 mockups和墨刀还有axure
  3. katka-container搭建
  4. dom4j解析dom示例
  5. 【linux】posix是什么都不知道,还好意思说你懂Linux?
  6. 【Linux】服务远程连接失败解决方法
  7. 随心所欲——享受恬淡的心态
  8. jieba.cut 和jieba.posseg
  9. 网络基础之网络布线、数制转换和子网划分
  10. 5/17/2015 今週日本語勉強の纏め