ZenBalance
ZenBalance

Reputation: 10317

How is it possible to cast an Android Activity to an interface?

In the Android documentation here: http://developer.android.com/guide/components/fragments.html A Fragment implements an interface.

In the onAttach() callback, it seems to cast the current Activity to an interface. Conceptually, how is this possible and is the same type of cast standard practice in vanilla 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");
        }
    }
    ...
}

Upvotes: 5

Views: 6122

Answers (4)

Hamed Ahmadi
Hamed Ahmadi

Reputation: 404

In Android Developer Guide doc, in Fragment section, in Creating event callbacks to the activity, written:

the mListener member holds a reference to activity's implementation of OnArticleSelectedListener

What is mListener?

Answer is:

An Object in type of Listener(interface), where an activity object is located in it! This activity object, in casting process, lost all field and method except same method with Listener interface. So, in the fragment, when we call mListener to do a method:

mListener.exampleMethod();

In simple word, "Hey mListener!" means, "Hey activity object, that lost all method except the ones that taken from interface", do that method!

I'm sorry for bad English!

Upvotes: 1

Balázs Édes
Balázs Édes

Reputation: 13807

Some basic knowledge about the topic:

Think about an interface as a bundle of functions. If a class implements an interface, then it guarantees, that it has all the interfaces functions implemented.

In your case:

If you have an object and you don't need more than the functions of an interface, that your object implements, then you can treat (and cast) that object to that interface. This way you loose "information" about your object, because you won't be able to use its functions (except the interface functions), but sometimes its enough.

Upvotes: 9

Cat
Cat

Reputation: 67522

Any object that is created from a class which implements some interface is also an instance of that interface.

Consider this:

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 {
        //
    }
}

In this case, the following is printed out: Main$MyClass@52c8c6d9 is Foo!. This indicates that the MyClass object is also an instance of MyFoo. Since they are shared instances, calling a cast to (MyFoo) mine would also be allowed.

This is, as @antlersoft said, part of vanilla Java (and can be seen here).

Because, in this case, the Activity passed to onAttach should always be the object which is both the Activity and the OnArticleSelectedListener, casting it to OnArticleSelectedListener should always succeed.

Upvotes: 5

antlersoft
antlersoft

Reputation: 14786

If the activity or one of its base classes is declared as implementing the interface, it is of course possible to cast it to the interface.

This is standard practice in vanilla Java.

If you aren't absolutely sure of the value onAttach is going to be called with, though, you should test with instanceof before you do the case.

Upvotes: 3

Related Questions