1
class One
{
    void show1()
    {
       System.out.println("super class");
    }

}

class Two extends One
{
    static void show2()
    {
       System.out.println("subclass");
    }


}
public class Cast 
{
    public static void main(String[] args)

    {
      One o=(One) new Two();
      o.show1();

    }

}

此语句在此代码中如何工作One o=(One) new Two();?为什么我不能这样使用 Two o=(One) new Two();?我对使用强制转换感到困惑,尽管这里的 o 是超类变量。为什么我不能使用 o 引用子类方法?

4

4 回答 4

3

此语句在此代码中的工作方式One o=(One) new Two();

这意味着 class 的对象Two是由 class 的引用创建和指向的One。不需要类型转换。

为什么我不能像这样使用Two o=(One) new Two();

那就是多态性。派生类不能指向基类。

经验法则:基类可以指向任何派生类。(反之亦然)。因此,您可以将派生类强制转换为基类,而不是其他方式。

虽然 o 这里是超类变量。为什么我不能使用 o 来引用子类方法。

对,但是实际对象是派生类的,而引用是基类的。只有那些在派生类中被覆盖的派生类方法才能被访问。

尝试以下代码行来查看自己:

Two obj = new One(); // Error
One obj = new Two(); // OK
Two obj = (Two) new One(); // Error

请参阅:ClassCastExceptionClassCastExceptionJava 中“ClassCastException”的解释

于 2013-02-06T06:44:14.470 回答
2

右侧的变量应该与左侧的类型(或任何子类型)相同。

One o=(One) new Two();

Two是 的子类型,One因此它可以转换为类型的One引用变量并且可以与类型的引用变量一起使用One

 Two o=(One) new Two();

在这里,您可以将类型Two转换One为向上转换的对象,但您不能将相同的转换对象分配给类型的引用变量,Two因为One它不是Two.

给定的层次结构是

One      
 |--> Two   

Two可以One在层次结构中的 One(One 的子类型)下代替它,但反之亦然。

于 2013-02-06T06:46:59.210 回答
1

该声明的工作原理

One o=(One) new Two();

类型的对象Two是在堆上创建的。但是引用o被强制转换为对类型的引用One

其实你可以这样做:

Two o = new Two();
o.show1();

因为Two也会有show1方法。

为什么我不能像这样使用 Two o=(One) new Two();

参考不匹配。但你可以这样做

Two o=(Two)(One) new Two();
于 2013-02-06T06:45:45.597 回答
1

为什么我不能使用 o 来引用子类方法。

这里show2方法仅存在于子类中,它不存在于超类中,并且您的对象 o 属于派生类,但您必须覆盖派生类中的方法,因此您无法访问show2。

于 2013-02-06T06:53:58.947 回答