为什么我允许将基类View转换为Android中的派生视图?

时间:2017-03-23 16:07:26

标签: java android

通常调用findViewById(int id)来返回所需的视图。但是,我们需要将返回的视图转换为我们需要的视图。像这样:

TextView myTextView = (TextView) findViewById(R.id.myTextView);

但是,当我创建基类和派生类时,我不能这样做。

public class Food {
    public String speak(){
        return "I'm a food!";
    }

}

public class Peach extends Food{

}

public class ClassePrincipal {
    public static void main (String args[]) { 
        Peach peach= (Peach ) new Food();
        System.out.println(peach.speak());
    }    

我收到以下错误: 运行:

  

线程“main”中的异常java.lang.ClassCastException:   PacoteMinicursoAndroid.Comida无法投出   PacoteMinicursoAndroid.Peach at   PacoteMinicursoAndroid.ClassePrincipal.main(ClassePrincipal.java:7)   C:\用户\米格尔\应用程序数据\本地\的NetBeans \缓存\ 8.1 \执行人-片段\ run.xml:53:   Java返回:1 FALHANACONSTRUÇÃO(翻译:在建筑时失败)(总时间:0秒)

为什么我可以像这样在Android中投放视图?

我无法真正看到将View转换为TextView(因为TextView从View扩展)和将Food转换为Peach(因为Peach从Food扩展)之间的区别。根据我对继承的了解,基类可以从派生类接收实例,而不是相反。

2 个答案:

答案 0 :(得分:0)

因为findViewById(R.id.myTextView)返回的View实际上是TextView,但编译器不知道。{1}}它只知道会有一个View对象,这就是为什么你通过强制它告诉编译器它是TextView的原因。

你的声明和演员是错误的

 Peach peach= (Peach) new Food();

因为虽然Food扩展Peach,但它永远不会是Peach对象,但始终是Food对象。 Typecasting是一个开发人员工具,可以在编译时为编译器提供更多信息。

答案 1 :(得分:0)

好的,我明白了。

因为允许findViewById(int id)返回一个View类,所以它也允许返回任何派生类,比如TextView。这是一种多态方法。

示例:

public class Food{

    public Food getPeach(){
        return new Peach();
    }
}

public class Pessego extends Comida{

}

然后在主方法中:

Food food = new Food();
Peach peach = (Peach) food.getPeach();

getPeach()是一个多态方法,就像findViewById(int id)一样。