将父类强制转换为其子类

7

我有:

class A
{
     public String getID() { return "id of A";}
}

class B extends A
{ 
     public String getID() { return "id of B"; }
}

and

class C {
 public A returnA() { 
    return new A(); 
  } 
}

现在我需要做的是:

C c = new C();
B b = (B)c.returnA(); 
String id = b.getId();

但是我没有访问C.returnA()的实现,并且我无法将其返回类型更改为B。


1
C语言不扩展A类型,因此您无法将A类型转换为C类型。 - LordSquall
2
你不是在试图将一个子类转换为其父类,而是在试图将一个父类(A)转换为子类(B)。显然这是行不通的。 - Jon Skeet
1
c.returnA() 返回 A,你不能强制转换为 B。将抛出 ClassCastException 异常。 - Elbek
没有一种机制可以自动将超类(A)的实例转换为子类(B)的实例。 - NPE
抱歉,将其重命名为将父级转换为其子级。 - inside
3个回答

20

您正在将父类转换为子类。这是不可能的,因为new A()绝对不是一个B

考虑一下:String extends Object。现在尝试将(String) new Object()进行转换。这根本没有任何意义。

因为您的对象无论如何都不是B,所以它无法具有B的行为。

您想要使用的是装饰器模式,请参见http://en.wikipedia.org/wiki/Decorator_pattern

以下是一个装饰器的实现示例:

public class B extends A {

    private A decorated;
    public B(A decorated) {
        this.decorated = decorated;
    }

    @Override
    public String getID() {
        return "id of B";
    }

    @Override
    public void otherMethodOfA() {
        return decorated.otherMethodOfA();
    }
}

请注意,必须覆盖 A 类的所有方法,以确保您在装饰元素上调用该方法。(这里otherMethodOfA 是一个示例)

使用方法如下:

C c = new C();
B b = new B(c.returnA());
String id = b.getID();

@Stanislav:关于装饰器,如果您提供B的哪些功能细节,我可以帮助实现。 - njzk2
@Stanislav:喏,给你。 - njzk2
1
在这种情况下,对于OP的问题,它将像这样进行:Object o = new Object(); String str = (String) o; o从一开始就不是一个String,所以强制转换没有意义。 - njzk2
@njzk2 我明白了。我没想到编译器会知道将被分配给 Object 的内容是什么。那么,如果 returnA() 方法返回 new B(),OP 的方法是否能正常工作? - parsecer
@parsecer 编译器不知道一个对象是哪个具体的实例,它只知道变量声明的类型,这就是为什么有时需要进行强制转换。OP 的例子可以编译,但在运行时会抛出异常。另外,是的A returnA(){return new B();} 然后 (B) returnA(); 可以正常工作,就像你的 String/Object 示例一样。 - njzk2
显示剩余2条评论

0

那样行不通。c.returnA()返回一个A。一个A不是B。(一个B是一个A,但这与此无关)。


-1

njzk2的答案非常完美。不过,如果你和我一样,不喜欢覆盖每个方法,你可以这样做:

public class B extends A {

    public B(A nonDecorated) {
        this.anotherValueOfA = nonDecorated.getAnotherValueOfA();
    }

    @Override
    public String getID() {
        return "id of B";
    }
}

没有必要覆盖每个方法,对象是使用其父级的值构建的。

当然,这是假设类A是:

class A {
    private int anotherValueOfA;
    public String getID() {return "id of A";}
    public int getAnotherValueOfA() {return this.anotherValueOfA;}
}

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