0

当您在 Java 中的超类类型的方法中返回子类时,我很难找到有关发生什么的细节。例如:

    public class SuperClass
    {
        int a;
    }
    public class SubClass extends SuperClass
    {
        int b;
    }


    SuperClass superObj;
    SubClass subObj;

    private SuperClass getObject ()
    {
        return subObj;
    }


    public static void main (...)
    {
        superObj = getObject();
    }

当 subObj 作为其超类返回时,它究竟会发生什么?我在输入这个例子时意识到,我自己也可以很容易地测试它,但我仍然很好奇发生这种情况时的具体过程是什么,以及它是否被认为是好的(如果它有效的话)还是不好的做法.

我之所以问,是因为我目前正在从事一个项目,其中我有两个抽象基类,每个基类都有几个子类。我试图找出处理必须从一个子类更改为另一个子类的好/坏方法,同时仍然使用使用抽象基类时添加的便利多态性。

编辑:我修复了 main 和 class 声明,对此感到抱歉。

4

3 回答 3

1

转换不会从根本上将对象更改为不同的类型,它只是告诉编译器将对象视为它的超类(或向下转换时的子类)。在您的示例中, superObj 仍然是 SubClass 类型的实例,但它现在似乎是 SuperClass。这意味着如果你尝试引用superObj.b,你会得到一个编译错误(因为 b 在 SuperClass 中不存在)。但是你可以参考(SubClass)superObj.b. 在这种情况下,您告诉编译器将 subClass 视为 SubClass 的一个实例(它确实是)。

让我们更进一步,在您的代码中添加另一个类:

public class SisterClass extends SuperClass
{
    int c;
}

在不更改代码中的任何其他内容(语法问题除外)的情况下,您尝试引用((SisterClass)superObj). 这将编译但因 ClassCastRuntime 运行时错误而失败。虽然 SisterClass 是 SuperClass 的子类,但 superObj不是SisterClass的实例。因此,您只能转换为 object 实际上什么。

于 2013-07-25T16:29:32.463 回答
0

SubClass 是 SuperClass 的扩展

您只是将其转换为它的基类,所有扩展都不可用,您不应该尝试将它们恢复为实现,因为您会猜测它们是什么,因为您可以通过各种方式对其进行多次扩展,

返回的类将有a但不是b

于 2013-07-25T16:06:59.210 回答
0

您的代码中有一些奇怪的地方(在 main 中定义了一个方法?),但这不能忍受...... getObject 方法不会更改您的 subObj,它只会返回一个看起来像 SuperClass 类型的引用。“看起来”是指它只会公开 SuperClass 中的任何方法或成员。但是,如果您采用该返回值并尝试将其向下转换为 SubClass,则转换将成功,您会发现 SubClass 中的字段/方法将按您预期的方式工作,而不会因作为 SuperClass 返回而丢失任何信息。

于 2013-07-25T16:11:12.243 回答