首页 > 解决方案 > 为什么我可以投射一个对象?可以用其他对象完成吗?

问题描述

所以我在写一个paintComponent(Graphics g)方法,一开始我意识到我正在将它转换为Graphics2D g2 = (Graphics2D) g;. 我前一阵子写了这段代码,只是意识到我不知道这是什么。我用谷歌搜索了一下,但对象转换对我来说有点陌生。

一个对象引用可以类型转换为另一个对象引用。这称为铸造对象。

^^逐字逐句摘自我的教科书 Y. Daniel Liang

我不明白为什么会这样。Graphics并且Graphics2D是两个不同的对象,它们如何相互继承实例变量和方法?显然,我知道原始铸造,即扩大和缩小。这是有道理的,因为它们只是 Integer、Double、Byte 等的包装类......

标签: javacasting

解决方案


使用强制转换不会发生任何类型的对象转换或转换。想象一下你有以下类结构:

class Mammal { }
class Human extends Mammal { }
class Dog extends Mammal { }

现在,当您创建一个新的 Human 实例时,Human human = new Human();它也将是一个哺乳动物,对吗?因此,您可以编写如下方法:

public void doSoemthing(Mammal mammal) {
    if (mammal instanceof Human) {
        Human human = (Human) mammal;
        human.doWork();
    } else if (mammal instanceof Dog) {
        Dog dog = (Dog) mammal;
        dog.bark();
    }
}

并调用如下方法:

doSomething(new Human());

因此,您的方法可以将任何类型的哺乳动物作为输入参数,并且在您的方法中,您可以检查它到底是哪种哺乳动物。因此,当您将 anew Human()作为输入传递时,对象的实际类型将是 Human。之所以可以将 Human 传递给期望 Mammal 的方法,是因为继承。所以你的方法会知道输入参数肯定是哺乳动物。但它可以是任何一种哺乳动物。例如,如果您想知道 Object 的实际类型是什么,可以使用instanceof。在这一行:

Human human = (Human) mammal;

并不意味着您正在转换哺乳动物输入参数。这只是意味着从现在开始您想将输入参数用作人类。你可以这样做,因为你可以检查它是否真的是一个人类。你也可以这样做:

public void doExample2(Object input) {
    if (input instanceof Integer) {
        System.out.println("I am a number");
    } else if (input instanceof Graphics) {
        System.out.println("I am a Graphics");
    }
}

注意输入参数的类型。对象是一切的基类。

所以回到你的场景。您执行该转换,因为从您的应用程序的上下文中,输入参数将始终是 Graphics2D,这就是您可以执行该转换以及使用 Graphics2D 提供的方法的原因。


推荐阅读