Как можно передать действие Android на интерфейс?

В документации по Android здесь: http://developer.android.com/guide/components/fragments.html Фрагмент реализует интерфейс.

В обратном вызове onAttach() он, похоже, переключает текущую активность на интерфейс. Концептуально, как это возможно и является одним и тем же типом стандартной практики литья в ванильной 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");
 }
 }
 ...
}
3 ответа

Некоторые базовые знания по теме:

Подумайте о interface как о наборе функций. Если a class реализует interface, то он гарантирует, что он имеет все реализованные интерфейсные функции.

В вашем случае:

Если у вас есть объект, и вам не нужно больше функций интерфейса, которые реализует ваш объект, вы можете обрабатывать (и отбрасывать) этот объект на этот интерфейс. Таким образом вы теряете информацию о своем объекте, потому что вы не сможете использовать его функции (кроме функций интерфейса), но иногда достаточно.


Любой объект, созданный из класса, который реализует некоторый интерфейс, также является экземпляром этого интерфейса.

Рассмотрим это:

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 (и ее можно увидеть здесь).

Поскольку в этом случае Activity, передаваемый в onAttach, всегда должен быть объект, который является как Activity, так и OnArticleSelectedListener, всегда следует выполнить его OnArticleSelectedListener.


Если действие или один из его базовых классов объявлено как реализация интерфейса, его можно, конечно, передать в интерфейс.

Это стандартная практика в ванильной Java.

Если вы не совсем уверены в том, что значение onAttach будет вызвано, вы должны проверить с instanceof перед тем, как это сделать.

licensed under cc by-sa 3.0 with attribution.