Android:Button类的ClassCastException

时间:2011-11-27 16:08:43

标签: java android classcastexception inheritance

我在使用自定义Button类时遇到问题。

我尝试将xml布局从<Button/>更改为<gButton/>,但这没有用。

我还尝试在第15行中投射Button page1 = (gButton) findView....,但由于某种原因无效(你可以投一个儿童课,对吗?)

我从LogCat得到的错误是:

Caused by: java.lang.ClassCastException: android.widget.Button
     at flash.tut.ButtonPage.onCreate(ButtonPage.java:15)

非常感谢任何帮助。

这是我的按钮视图:

public class ButtonPage extends Activity{
     public void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
         setContentView(R.layout.button);

         gButton page1 = (gButton) findViewById(R.id.Button01); //<---LogCat: ClassCastException
         page1.setOnClickListener(new View.OnClickListener() {
              public void onClick(View view) {
                   Intent mI = new Intent(view.getContext(), Page1.class);
                   startActivityForResult(mI, 0);
              }
         });
     }
}

和我扩展按钮类的gButton:

public class gButton extends Button{
    private static Context con;

    public gButton(){this("Blank");}

    public gButton(String name){
        this(name, R.color.text_color);
    }

    public gButton(String name, int col) {
        this(name, col, con);
    }

    public gButton(String name, int col, Context context) {
        super(context);   //necessary context...dont know why.
        setBackgroundResource(R.drawable.icon);
        setTextColor(col);
        setText(name);
        setTextSize(14);
    }
}

最后我的xml布局:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent">

 <Button android:text="Page 1"
        android:id="@+id/Button01"
        android:layout_width="250px"
        android:textSize="18px"
        android:layout_height="55px">
    </Button>

 <Button android:text="Page 2"
        android:id="@+id/Button02"
        android:layout_width="250px"
      android:textSize="18px"
        android:layout_height="55px">
    </Button>

 <Button android:text="Page 3"
        android:id="@+id/Button03"
        android:layout_width="250px"
      android:textSize="18px"
        android:layout_height="55px">
    </Button>

<Button android:text="ListView Page"
        android:id="@+id/ButtonList"
        android:layout_width="250px"
      android:textSize="18px"
        android:layout_height="55px">
    </Button>

</LinearLayout>

2 个答案:

答案 0 :(得分:2)

要将按钮投射到gButton,您应该声明如下按钮:

<com.example.gButton 
    android:text="Page 3"
    android:id="@+id/Button03"
    android:layout_width="250px"
    android:textSize="18px"
    android:layout_height="55px">
</com.example.gButton>

但是你应该把你的包装而不是“com.example”

你的gButton类必须有下一个构造函数:

package com.example;

public class gButton extends Button{
    ...

    public gButton(Context context, AttributeSet attrs) { // this constructor will be called by inflater for creating object instance
        super(context, attrs);
    }

    ...

}

然后您可以按照您在问题中所写的方式投射按钮。但请注意,您的构造函数不会被称为

答案 1 :(得分:1)

当您尝试将按钮强制转换为按钮时,Button01是一个按钮。除非对象是派生对象,否则无法将对象强制转换为派生对象。例如,您有一个名为Product的基类,它由CartItem扩展。

现在,还可以想象除了CartItem之外,Product还有其他派生类,例如PhoneItem和MailOrderItem。

你不能这样做: 产品prod =新产品(); CartItem cart =(CartItem)prod。

为什么呢?

因为“prod”不是CartItem,而是PhoneItem和MailOrderItem。您将其创建为“产品”项目,无论您如何尝试投射它,它都将始终是一个产品项目。您可以强制它为MailItem或PhoneItem。

但是,如果您执行以下操作,则可以: CartItem cart = new CartItem(); 产品产品=(产品)推车; CartItem cart2 =(CartItem)prod;

或者

产品prod = new CartItem(); //(隐式转换为产品) CartItem cart2 =(CartItem)prod;

为什么这样做?因为CartItem也是产品(虽然并非所有产品都是购物车产品)。即使你把它投放到产品上,它仍然是,并且将永远是一个CartItem。唯一的区别是CartItem的当前句柄碰巧是一个Product句柄,让您可以更有限地访问CartItem可以拥有的所有功能。当你试图将它从Product转发回CartItem时,运行时引擎会说,“嘿,我可以将这个目标对象转换成他们想要的类型吗?”此时,它查看目标对象,并发现该对象在当前被引用为Product时,实际上是一个已经向上转换的CartItem。因此,将其重新投入到最初的CartItem是安全的。再一次,重点是,一旦你将它创建为CartItem,无论你向上或向下投放多少次,它总是一个CartItem。但是,在您给出的示例中,您的产品项目绝不仅仅是一个简单的产品。它从来都不是一个CartItem开始并且无法投入使用。