Reputation: 10317
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
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
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
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
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