9

我试图向上转换一个对象。但是在运行时对象类仍然作为派生类。

Derived drv = new Derived();

Base base = (Base) drv;

System.out.println("Class : " + base.getClass()); 

//prints -> Class : class packagename.Derived

那么为什么类属性没有改变?

4

3 回答 3

14

那么为什么类属性没有改变?

因为对象没有改变,只是你对它的引用类型。投射对对象本身没有任何影响。

在 Java 中,与其他一些语言不同(谢天谢地),引用的类型在很大程度上不会影响您获得的方法版本。例如,考虑这两个类(由2rs2ts提供 ——谢谢!):

class Base {
    public Base() {}
    public void foo() {
        System.out.println("I'm the base!");
    }
}

class Child extends Base {
    public Child() {}
    public void foo() {
        System.out.println("I'm the child!");
    }
}

这段代码:

Child x = new Child();
Base y = (Base) x;
y.foo();

...输出

我是孩子!

因为即使类型yis Base,我们调用的对象foo也是 a Child,所以Child#foo会被调用。这里(再次由2rs2ts提供)是一个关于 ideone 的示例

Child#foo尽管经历了引用,但我们得到的事实Base对于多态性至关重要。

现在,恰好你调用的方法 ( getClass)只能Object#getClass,因为它是一个final方法(子类不能覆盖它)。但这个概念很重要,我认为它可能是你所问问题的核心。

引用类型的主要作用是确定允许访问对象的哪些方面。例如,假设我们添加barChild

class Child extends Base {
    public Child() {}
    public void foo() {
        System.out.println("I'm the child!");
    }
    public void bar() {
        System.out.println("I'm Child#bar");
    }
}

此代码不会编译:

Child x = new Child();
Base y = (Base) x;
y.bar(); // <=== Compilation error

...因为Base没有bar方法,所以我们不能通过bartype 的引用访问对象的方法Base

于 2014-03-18T13:05:05.917 回答
0

您不能在 Java 中更改实例的类型。您对演员表所做的只是从不同类型的变量中引用它。

于 2014-03-18T13:05:09.230 回答
0

upcast 不会改变对象的类型。事实上,NOTHING 不会改变 Java 对象的类型。

这就是 OO 编程的核心:对象具有不受外部影响的已定义行为。

于 2014-03-18T13:06:52.800 回答