【问题标题】:Typecasting an object from parent class to child将对象从父类类型转换为子类
【发布时间】:2014-08-07 22:04:03
【问题描述】:

我对 Java 语言中的类型转换有一个误解。问题是ClassCastException。例如,在这段代码中,假设 Animal 是 Dog 类的父类,

Animal 动物 = new Animal();
Dog dog = (Dog) 动物;

在执行后抛出 ClassCastException。 然而,在研究 android 包时,我发现了一个关于类型转换的示例,考虑到那个 java 示例,它应该抛出一个 ClassCastException

EditText editText = (EditText) findViewById(R.id.edit_message);

在这段代码中,findViewById方法返回一个View类对象,它是EditText类的超类之一。(来自android.view.Viewandroid.widget.EditText) 代码运行良好。谁能解释我是否犯了错误或这是怎么发生的?

提前致谢。

【问题讨论】:

  • 如果您知道如何用polymorphism 标记这个问题,您就知道如何在此站点或其他地方搜索该概念。说真的,这太基础了。发帖前先搜索一下。
  • 问题不在于多态机制,我知道这个例子确实包含多态性。真正的问题是关于 android 的实现。我知道为什么它给出了异常,我要求澄清 android 代码。
  • 没有“Android 实现”。将对象视为其祖先父对象是多态性的核心,这是 OOP 的关键方面,因此也是 Java(以及 Android)的关键方面。我的评论试图告诉你,你发布这样一个基本问题的速度太快了,在 SO 或 Google 中执行简单搜索(或彻底阅读 developer.android.com)很容易回答这个问题

标签: java android types casting polymorphism


【解决方案1】:

一旦你创建了一个对象,你就不能改变它的类型。这就是为什么你不能将动物施用于狗。

但是,如果创建子类的对象,可以在超类类型的变量中保留对它的引用,以后可以将其强制转换为子类类型。

这将起作用:

Animal a = new Dog ();
Dog d = (Dog) a;

在 Android 示例中,您有一个如下所示的布局资源:

<EditText
    android:id="@+id/edit_message"
 ..."/>

此定义将导致 Android 创建EditText 的实例,因此您可以将findViewById 返回的视图强制转换为EditText。您不能将其转换为不是EditText 的超类型的任何其他东西。

【讨论】:

  • 好的,我了解这种类型转换的工作原理。然而,android 的例子让我很困惑。如果我不实例化子类中的对象,我可以像 android 示例中那样将每个超类对象转换为子类对象吗?我将编写一个方法而不是直接类型转换:“父类” public Animal foo(){ Animal animal2 = new Animal();返回动物2; } 和“子类” Dog dog = (Dog) animal.foo();这仍然给出了异常。
  • @mwb 不,在 Android 示例中,Android 根据布局 xmls 中的定义实例化对象。您只能将其转换为正确的子类型。
  • 你应该阅读 java 中的多态性和类型转换,在 Android 中没有什么不寻常的事情发生。
  • @mwb 在这种特殊情况下,Android 会进行实例化,但您会在许多从定义文件中实例化对象的面向对象平台中遇到这种行为。
【解决方案2】:

基本上,您不能将超类的实例转换为子类,因为子类的实例尚不清楚。向上转型是防止这种异常发生的可靠方法,因为我们现在正在处理我们的代码的多态性。

你必须先实例化一个子类:

Dog dog = new Dog;

我们可以将 Dog not found 类的方法隐藏到它的父类 Animal 中,方法是将它转换为它的超类:

Animal animal = (Animal) dog;

然后你可以向下转换回你的子类 Dog 因为它的子类的实例是已知的:

Dog anotherDog = (Dog) animal;

【讨论】:

    【解决方案3】:

    你可以试试这个:

    Base obj= new Derived();
    Derived obj2= (Derived)obj;
    

    希望这会有所帮助。

    【讨论】:

      【解决方案4】:
      public class OverridingConcept {
          public static void main(String[] args) {
              // Up-Casting
              Parent p = new Child();
              Child c = (Child) p;
              c.eat();
          }
      }
      class Parent {
          void show() {
              System.out.println("Parent.Show");
          }
          void eat() {
              System.out.println("Parent.Eat");
          }
      }
      class Child extends Parent {
          void show() {
              System.out.println("Child.Show");
          }
          void sing() {
              System.out.println("Child.Sing");
          }
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2022-11-18
        • 1970-01-01
        • 2023-03-19
        • 2018-11-27
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多