【问题标题】:How is it possible to cast an Android Activity to an interface?如何将 Android Activity 转换为界面?
【发布时间】:2012-08-30 19:43:27
【问题描述】:

在此处的 Android 文档中:http://developer.android.com/guide/components/fragments.html A Fragment 实现了一个接口。

在 onAttach() 回调中,似乎将当前 Activity 转换为接口。从概念上讲,这怎么可能,并且是原版 Java 中相同类型的强制转换标准实践?

public static class FragmentA extends ListFragment {


// Container Activity must implement this interface
    public interface OnArticleSelectedListener {
        public void onArticleSelected(Uri articleUri);


    OnArticleSelectedListener mListener;



    @Override
    public void onAttach(Activity activity) {
        super.onAttach(activity);
        try {
            mListener = (OnArticleSelectedListener) activity;
        } catch (ClassCastException e) {
            throw new ClassCastException(activity.toString() + " must implement OnArticleSelectedListener");
        }
    }
    ...
}

【问题讨论】:

    标签: java android


    【解决方案1】:

    从实现某个接口的类创建的任何对象也是该接口的实例。

    考虑一下:

    public class Main {
        public static void main(String[] args) {
            MyClass mine = new MyClass();
            checkIsFoo(mine);
        }
    
        public static void checkIsFoo(MyClass mine) {
            System.out.print(mine+"");
            if (mine instanceof MyFoo)
                System.out.println(" is Foo!");
            else
                System.out.println(" is not Foo!");
        }
        public static interface MyFoo {
            //
        }
        public static class MyClass implements MyFoo {
            //
        }
    }
    

    在这种情况下,将打印出以下内容:Main$MyClass@52c8c6d9 is Foo!。这表明MyClass 对象也是MyFoo 的一个实例。由于它们是共享实例,因此也允许调用对 (MyFoo) mine 的强制转换。

    正如@antlersoft 所说,这是原版Java 的一部分(可以在here 看到)。

    因为在这种情况下,传递给onAttachActivity 应该始终ActivityOnArticleSelectedListener 的对象,将其转换为OnArticleSelectedListener 应该总能成功。

    【讨论】:

      【解决方案2】:

      关于该主题的一些基本知识:

      interface 视为一组函数。如果class 实现了interface,那么它保证它已经实现了所有接口函数。

      在你的情况下:

      如果您有一个对象,并且您不需要的只是您的对象实现的接口的功能,那么您可以将该对象处理(并强制转换)到该接口。这样你就失去了关于你的对象的“信息”,因为你将无法使用它的功能(除了接口函数),但有时它已经足够了。

      【讨论】:

        【解决方案3】:

        在 Android 开发人员指南文档中,在 Fragment 部分中,在为 Activity 创建事件回调中写道:

        mListener 成员持有一个 reference 到 Activity 的 OnArticleSelectedListener 实现

        什么是mListener?

        答案是:

        Listener(interface) 类型的对象,其中有一个活动对象! 此活动对象在转换过程中,除了与 Listener 接口相同的方法外,丢失了所有字段和方法。所以,在片段中,当我们调用 mListener 做一个方法时:

        mListener.exampleMethod();
        

        简单来说,“嘿,mListener!”意思是,“嘿活动对象,除了从接口获取的方法之外,它丢失了所有方法”,执行该方法!

        对不起,我的英语不好!

        【讨论】:

          【解决方案4】:

          如果活动或其基类之一被声明为实现接口,当然可以将其强制转换为接口。

          这是原版 Java 中的标准做法。

          但是,如果您不确定要调用 onAttach 的值,则应在执行此案例之前使用 instanceof 进行测试。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2023-03-13
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2014-07-28
            • 1970-01-01
            相关资源
            最近更新 更多