【问题标题】:extending superclass and ClassCastException扩展超类和 ClassCastException
【发布时间】:2011-05-14 17:40:14
【问题描述】:

我有一个超类,我想重写这两个方法。这是我的代码:

public class MyCustomClass extends SomeSuperClass {

protected MyCustomClass(params) {
    super(params);
}
@Override
public void method1() {
    super.method1();
    /* here goes my code */
}
@Override
public void method2() {
    super.method2();
    /* here goes my another code  */
}

我有一些构造函数,将 SomeSuperClass 对象作为参数传递,接下来我要做什么:

MyCustomClass object;
/* now i have object of type SomeSuperClass,
but with my own method1() and method2() */
object = (MyCustomClass) MyCustomClass.item(blahblah); 
/* eclipse suggests casting, because MyCustomClass.item()
 constructor still returns SomeSuperClass object */
otherobject = OtherConstructor.object(object);
//OtherConstructor passes SomeSuperClass object 

这似乎是对的,但我在执行时在 SomeSuperClass 中得到 java.lang.ClassCastException。

如果我创建 SomeSuperClassObject,我会丢失我的重写方法。

使用强制转换,即使 eclipse 中没有错误,应用程序也会崩溃。 换句话说,我如何用我自己的方法覆盖 SomeSuperClass,并且仍然让 SomeSuperClass 对象与 OtherConstructor 一起使用? 如果很重要,此代码适用于 android 应用程序。

【问题讨论】:

  • MyCustomClass.item 的代码是什么?
  • 它没有被覆盖,所以它(确实是,根据 eclipse 代码助手)只是使用超类方法
  • 学究式,MyCustomClass.item() 不是“构造函数”,OtherConstructor.object()也不是

标签: java casting overriding classcastexception superclass


【解决方案1】:

如果在SomeSuperClass 中声明了item() 方法,我怀疑它返回的是MyCustomClass 的实例。所以你的演员 (MyCustomClass) MyCustomClass.item(blahblah) 将是无效的。

【讨论】:

  • 为什么不呢?如果他在编译时有两个 botch 类,则父类中的静态方法 item() 可以返回特定的子类实例(如某种简单的工厂方法)...
  • 是的,你是对的,它可以这样写;但我比较怀疑。我会改写。
【解决方案2】:

作为一般规则,您可以将子类的实例强制转换为其父类:

MyCustomClass object = new MyCustomClass(params);
SomeSuperClass superClass = (SomeSuperClass) object;

但是,您不能将超类的实例强制转换为子类:

SomeSuperClass object = new SomeSuperClass(params);
MyCustomClass customClass = (MyCustomClass) object; // throws ClassCastException

这是因为MyCustomClass 对象也是SomeSuperClass 对象,但并非所有SomeSuperClass 对象都是MyCustomClass 对象。

您可以使用某些设计模式来解决此问题。 Java 本身倾向于大量使用Decorator pattern

【讨论】:

  • 我总是忘记哪个方向可以。这有帮助。
【解决方案3】:

从我所见,MyCustomClass.item(blahblah) 调用返回的内容似乎与 MyCustomClass 不同(可能是父级)。它是 te 代码中唯一的部分,您在其中投射对象...

【讨论】:

  • 这就是您的问题,您不能将父实例强制转换为子实例。继承结构可以翻译成 IS 语言结构。在您的情况下,您有一个 Mammal(超类)和 Human(子类)和 Rabbit 子类。您可以创建人类 h 并说“h 是哺乳动物 (Mammal m = new Human())”,但不能说每个哺乳动物都是人类 (Mammal m = new Rabit; Human h = (Human) m)...这就是你所做的,以及为什么你有 classcastexception...
  • 在我看来,您犯的错误略有不同...您说 Human h = new Mammal(),但事实并非如此,因为抽象哺乳动物(您的超类)有 4 条腿,并且人类有 2 条手和 2 条腿......所以你不能将对父级的引用投射到子级......只有当父级引用包含子对象时才能执行此操作(哺乳动物 m = new Human(); Human h =(人类)m)-你说这个人是哺乳动物-这个具体的哺乳动物(不会为每一个哺乳动物工作)是一个人。
【解决方案4】:

看起来问题已解决。我试过了

object = new MyCustomClass(blahblah);

它奏效了。 顺便说一句,有人可以解释一下吗?

【讨论】:

  • 我知道这已经很老了,但它可能仍然对寻找答案的人有所帮助。当然,这是可行的,因为它是通过构造方法创建对象的标准方式。作为参考,如前所述,您可以创建由父类变量指向的子类对象。因此,原始对象始终是子对象,但现在被引用为父变量。这可以随时向下转换为由子变量指向。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-12-26
  • 1970-01-01
  • 2011-01-01
  • 1970-01-01
相关资源
最近更新 更多