Java中的上转型和下转型混淆

4

好的。所以如果...

int x=3;
int y=5;


x=y;

那么x=5,对吗?

好的,如果BA的子类...

A a=new A();
B b=new B();

a=b;

为什么这被认为是向上转型?

"a" 不应该变成 "b" 而不是相反吗?有人能向我解释一下吗?

4个回答

11

我们不谈论抽象的A和B,来看一个具体的例子。

class Person {
    public void greet() {
        System.out.println("Hello there!");
    }
}

class ComputerScientist extends Person {    // Does he, really?
    @Override
    public void greet() {
        System.out.println("Hello there! I work at the Informatics Department.");
    }

    public void validateAlgorithm(Algorithm a)
            throws InvalidAlgorithmException {
        // ...
    }
}

当你有一个计算机科学家作为

ComputerScientist cs = new ComputerScientist();

您可以访问greetvalidateAlgorithm。您知道他/她是一个Person,并且可以像对待其他人一样向他/她greet。但是,您也可以将他/她特别视为ComputerScientist

当您将此对象分配给Person类型的变量时,您所做的只是说:"我不再关心你是一个ComputerScientist了。从现在开始,我将像对待任何其他Person一样对待你。"

Person p = cs;

相当于

Person p = (Person) cs;
p所指的对象仍然知道如何validateAlgorithm,并且仍然告诉你他在信息系学院工作。但是,通过p访问它时,告诉编译器你只想问候这个Person,不需要其他信息。
这被称为向上转型,因为变量在继承关系树中向上移动,其中向上表示更一般/抽象,向下表示更具体。你正在将一个ComputerScientist泛化成一个Person

7

在执行 a = b; 后,变量 a(声明为类型 A)将引用类型为 B 的对象。因此,此赋值涉及隐式向上转型:a = (A)b;,将 Java 视图中的 bB 转换为其超类 A。这就是一次向上转型。


1
请注意,尽管b所引用的对象将被视为A,但在a = b之后,所引用的对象仍然是B,它并没有被字面上转换。例如,所有重写的方法仍然被重写。 - afsantos

1
A a = new A();
B b = new B();

流程如下:
  • 使用 new A() 创建 A 对象并将其赋值给引用变量 a;同样,使用 new B() 创建 B 对象并将其赋值给引用变量 b。
  • 需要注意的是,求值从右侧到左侧进行,这就是为什么首先计算右侧并将结果分配给相应变量的原因。

现在来看看你所遇到的问题——为什么 a=b 是向上转型。

  • 对于这个语句,上述点也适用,首先计算子类 b。由于您正在将子类分配给超类,因此会进行隐式转换,从子类型转换为超类型,这当然是向上转型。

这个链接可以让它更清晰 https://www.youtube.com/watch?v=Wh-WZXCAarY

希望这有所帮助。


0

那么x的值就是5了,对吧?

没错。

好的,如果B是A的子类...

为什么这被认为是向上转型呢?

因为它就是向上转型。

难道不应该是"a"变成"b"而不是反过来吗?

是的,确实如此。对B的引用向上转型为对'A'的引用。


3
这真正回答了问题吗?OP问的是为什么。你重复了OP已经知道的内容。 - Suresh Atta

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接