传值过程中 父类变量的类型变成子类

来源:2-4 使用泛型

codepracitce

2021-11-08 23:25:32

Student bobo = new Student(“Bobo”);

Object stu = bobo;

  Stu的类型为什么就变成Student了?

传值过程我们将一个学生类对象传给了Object类对象,我们称stu是一个上转型对象,那为什么上转型对象的类类型.getClass()是子类类型

尝试过的解决方式:调用栈显示是子类类型 也就是学生类

写回答

1回答

liuyubobobo

2021-11-09

getClass 返回的是运行时类型(runtime type)。


如果 B 是 A 的子类。当我们写 A o = new B() 的时候,o 可以做为 A 被识别,同时还能够访问 B 的所有方法,这是多态的关键。你可以理解成 getClass 返回的就是 o “真正”的类别。(而非向上转型的类型)。


可以做一个简单的测试:

Object o = new String("abc");
System.out.println(o.getClass());

将打印出 String 类型。



==========


为什么说这是多态的关键?考虑一个最简单的场景。多态允许用一个父类数组,承载诸多的子类对象。


比如有一个 Shape 类,Square 和 Circle 是 Shape 的子类。


public class Shape {
    @Override
    public String toString(){
        return "I'm a Shape!";
    }
}

public class Square extends Shape{
    @Override
    public String toString(){
        return "I'm a Square!";
    }
}

public class Circle extends Shape{
    @Override
    public String toString(){
        return "I'm a Circle!";
    }
}


我们可以用一个 Shape 数组,承载 Square 和 Circle 类的对象。

Shape[] arr = new Shape[2];
arr[0] = new Square();
arr[1] = new Circle();


现在,我们通过 arr 访问的对象,就找不到 Square 类或者 Circle 类的方法了吗?当然不是,如果那样,多态就失去了意义。多态的意思恰恰就是“多种形态可以放在一起”。所以,如果我们打印 arr 数组中的每一个对象,你会看到 Square 或者 Circle,而不是 Shape。

for(Shape shape: arr)
    System.out.println(shape);
    
/// 打印结果是:
/// I'm a Square!
/// I'm a Circle!
///
/// 而不是
/// I'm a Shape
/// I'm a Shape


Java 是怎么知道 Shape 数组中每一个对象是 Square 还是 Circle 的?就是靠运行时类型。也就是 Java 记住了每一个对象“真正”的类型。调用 getClass,就可以得到这个“真正”的类型,即运行时类型。


==========


运行时类型不是这个课程的重点,如果对这一点感兴趣,可以在网上搜索“运行时类型”或者“runtime type”了解更多。通常 Java 相对高级的讲义或者教材也会介绍这个概念的。这个概念也和 Java 的诸多其它特性,比如反射,动态绑定,等等概念联系在一起。或者更广泛一些,所有编程语言其实都有相关的概念。(只不过表现方式不同)。


继续加油!:)

3
hodepracitce
hp dir="ltr">好的注意身体早点休息

h021-11-09
共1条回复

算法与数据结构

波波老师5年集大成之作,算法与数据结构系统学习,考试、面试、竞赛通用

2603 学习 · 1086 问题

查看课程