(Android)接口回调

(Android)接口回调


1、什么是接口回调

那么何为接口回调呢?

接口回调是指:

可以把使用实现了某一接口的类创建的对象的引用,赋给该接口声明的接口变量,那么该接口变量就可以调用被类实现的接口的方法。实际上,当接口变量调用被类实现的接口中的方法时,就是通知相应的对象调用接口的方法,这一过程称为对象功能的接口回调。

接口回调说白了就是通过接口来调用接口里面的方法

2、接口回调的作用

  • 最主要的作用便是解耦

    • 削弱模块间的协作性,也就是耦合性,使得模块之间高度独立,模块间更多的从事着单向的调用工作。一个模块需要某种服务就去找另一个模块,这使得程序呈现出层次性,高层通过接口调用底层,底层提供服务。摈弃模块间你中有我我中有你的暧昧关系。
  • 模块间的相互协作

    • 但我们又需要模块间的协作,所以需要回调(C++中是指针)。如果A对象关心B对象的状态变化,那么给B对象的状态的变化注册接口回调函数,A实现接口,让接口函数通知A,B对象状态的改变,这样在封装了模块变化的同时实现了模块间的协作关系,另辟独径的给对象解耦。
  • 函数的参数

    • 回调函数跟普通函数只是在调用函数时略有区别。一般调用普通函数时,直接写函数名即可。但是在调用所谓“回调”函数时,是把它作为参数传递给另一函数。关键就在于“参数”这两个字。为什么要把某个东西参数化?就是它存在变化的可能性。既然可以把变量做成参数,那么函数也同样可以做成参数,只要它们有变化的可能。对于一成不变的东西,显然直接嵌入便可。

3、Java中的引用

  1. 如果a是类A的一个引用,那么a可以指向类A的一个实例。或者说指向类A的一个子类,这是向上转型的情形。
  2. 如果a是接口 A 的一个引用,那么a必须指向实现了接口A的一个类的实例。这是接口回调的情形。

为了直观我就直接上代码,如下:

interface Animal{  
   void eat();  
}  
class dog implements Animal{  
   public void eat(){  
    System.out.println("狗吃肉");  
}  
}  
class cat implements Animal{  
  public void eat(){  
    System.out.println("猫吃老鼠");  
}  
}  
public class Example{  
  public static void main(String args[]){  
    Animal a;             //声明接口变量  
a=new dog();      //实例化,接口变量中存放对象的引用  
a.eat();        //接口回调,具体如何运行有实现类重写抽象方法  
a=new cat();     //实例化,接口变量中存放对象的引用  
a.eat();       //接口回调  
}  
}  

结果为:

狗 吃 肉
猫 吃 老 鼠
  • 咋一看可能会有人说这不就是多态的用法吗?没错,实际上与多态并无太大的区别(建议顺便复习一下多态方面的知识)。

4、案例分析

  • 比较经典的案例为OnClickListener点击事件,因比较常见在这里就不做赘述。本案例比较简单主要功能为:从Fragment中利用接口回调的方式向Activity中传递数据,具体代码如下:
    Fragment类

    public class EditFragment extends Fragment {
        private EditText et;
        private Button but;
        //1. 创建一个接口以及抽象方法
        public interface TextCallback {
            //将想要传递出去的数据作为抽象方法的参数列表
            void getText (String str);
        }
        //2. 定义一个接口类型的变量,并给该变量进行初始化操作
        private TextCallback callback;
        public void setCallback(TextCallback callback) {
            this.callback = callback;
        }
        @Override
        public View onCreateView(LayoutInflater inflater, ViewGroup container,
                Bundle savedInstanceState) {
            // TODO Auto-generated method stub
            return inflater.inflate(R.layout.myfrag, container,false);
        }
        @Override
        public void onViewCreated(View view, Bundle savedInstanceState) {
            // TODO Auto-generated method stub
            super.onViewCreated(view, savedInstanceState);
            initView(view);
            but.setOnClickListener(new OnClickListener() {
                @Override
                public void onClick(View v) {
                    // TODO Auto-generated method stub
                    String str = et.getText().toString();
                    /*
                    通过接口回调的方式
                    //3. 通过接口对象调用抽象方法
                    callback.getText(str);
                }
            });
        }
    }
    

    在 EditFragment中有一个EditText和一个Button在EditText中输入内容点击按钮输入的内容便会显示在MainActivity中的TextView上,从而实现从EditFragment向MainActivity中传递数据。当通过接口对象调用抽象方法即:callback.getText(str);时具体实现是方法为MainActivity中重写的getText方法。

MainActivity类

public class MainActivity extends Activity {
    private TextView tv;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        tv = (TextView)findViewById(R.id.textView1);       
        EditFragment ef = new EditFragment();
        //给接口赋值,
        ef.setCallback(new TextCallback() {
            //当在Fragment中通过接口对象调用抽象方法时运行以下方法
            @Override
            public void getText(String str) {
                // TODO Auto-generated method stub
                tv.setText(str);
            }
        });
        //将EditFragment添加到屏幕上显示
        getFragmentManager().beginTransaction().replace(R.id.frame, ef ).commit();
    }   
}
发布了34 篇原创文章 · 获赞 3 · 访问量 3万+

猜你喜欢

转载自blog.csdn.net/The_king_of_Asia/article/details/53943810