Java|今天起,別再扯訂閱和回調函數


 

編程史上有兩個令人匪夷所思的說辭,一個是訂閱,一個是回調函數。

 

我想應該還有很多同學為“事件的訂閱”和“回調函數”所困擾,因為事情本來就不應該按這個套路來解釋。

 

 

多直白,所謂的“回調函數”你完全可以線性的理解它,現在起,你只需要知道“接口”與“實現”!

常見的場景如下:


1.我寫了個模塊,模塊中有一些功能要實現,但我暫時沒空做,或者需要他人的協助來完成具體的實現。因此我先定義一個接口,接口中根據我的需要定義一些空方法,在我的模塊中調用這些空方法,這些方法的具體實現交給未來實現該接口的類中去實現。

 

2.我寫的是可復用的控件,例如點擊它會完成什么功能,需要使用他的人到時候自行去填寫。因此我先定義一個接口,接口中根據我的需要定義一些空方法,在我的控件中調用這些空方法,這些方法的具體實現交給未來實現該接口的類中去實現。

 

3.我在設計模塊,就像羅列大綱一樣,在接口中把該有的方法大致羅列出來,然后由實現這個接口的類來實現這些方法。

 

4.我寫了個模塊,有些功能適合放在特定的類中去實現。因此我先定義一個接口,接口中根據我的需要定義一些空方法,在我的模塊中調用這些空方法,這些方法的具體實現交給未來實現該接口的類中去實現。

 

……

有沒有發現,盡管出於不同的目的,但是他們的套路都是一樣的:

 

1.定義接口,接口中定義空方法

 

2.在不方便或不適合實現方法的地方調用這些空方法

 

3.在實現該接口的類中具體實現這些方法

 

對於調用空方法的地方來說,他們調用未來會被實現的空方法,和直接調用一個現成的方法,效果是一樣的。

可能光看文字描述並無助於你的理解,那么下面的代碼,幫助你順流直下秒懂這一切。

1.我寫了一個可復用的控件,里面有個按鈕的點擊事件需要放在未來調用該控件的Activity中實現

 1 public class TitleBar extends RelativeLayout {
 2 
 3     public TitleBar(Context context, AttributeSet attrs, int defStyleAttr) {
 4         super(context, attrs, defStyleAttr);
 5     }
 6 
 7     public TitleBar(Context context) {
 8         super(context);
 9     }
10 
11     public TitleBar(Context context, AttributeSet attrs) {
12         super(context, attrs);
13 
14         LayoutInflater.from(getContext()).inflate(R.layout.title_bar, this);
15     }
16 
17     private Button btnBack;
18 
19     private void initView() {
20         btnBack = (Button) this.findViewById(R.id.btn_back);
21         btnBack.setOnClickListener(new OnClickListener() {
22             @Override
23             public void onClick(View v) {
24 
25             }
26         });
27     }
28 }

 

2.因此我定義一個接口,其中定義控件點擊事件中要執行的方法的空方法,然后在控件的點擊事件中調用該空方法。

 1 public class TitleBar extends RelativeLayout {
 2 
 3     public TitleBar(Context context, AttributeSet attrs, int defStyleAttr) {
 4         super(context, attrs, defStyleAttr);
 5     }
 6 
 7     public TitleBar(Context context) {
 8         super(context);
 9     }
10 
11     public TitleBar(Context context, AttributeSet attrs) {
12         super(context, attrs);
13 
14         LayoutInflater.from(getContext()).inflate(R.layout.title_bar, this);
15         initView();
16     }
17 
18     private Button btnBack;
19 
20     private void initView() {
21         btnBack = (Button) this.findViewById(R.id.btn_back);
22         btnBack.setOnClickListener(new OnClickListener() {
23             @Override
24             public void onClick(View v) {
25                 //5.調用該接口的該空方法
26                 mTitleBarListener.btnBackClick();
27             }
28         });
29     }
30 
31     //1.定義該接口
32     public interface TitleBarListener {
33         //2.定義該空方法
34         void btnBackClick();
35     }
36 
37     //3.在控件中定義一個該接口的成員變量
38     private TitleBarListener mTitleBarListener;
39 
40     //4.為該接口成員變量定義一個set方法,用於從實現類中傳入接口的實例
41     public void setOnTitleBarListener(TitleBarListener titleBarListener) {
42         this.mTitleBarListener = titleBarListener;
43     }
44 }

 

3.在Activity中使用該控件,傳入該接口的實例,並實現該方法

 1 public class ActivityOne extends AppCompatActivity {
 2 
 3     @Override
 4     protected void onCreate(@Nullable Bundle savedInstanceState) {
 5         super.onCreate(savedInstanceState);
 6         setContentView(R.layout.aty_one);
 7         initView();
 8     }
 9 
10     private TitleBar titleBar;
11 
12     private void initView() {
13         titleBar = (TitleBar) findViewById(R.id.titleBar);
14         //6.調用該接口的set方法,將接口的實例傳入並具體實現控件中調用的空方法
15         titleBar.setOnTitleBarListener(new TitleBar.TitleBarListener() {
16             @Override
17             public void btnBackClick() {
18                 //此處填充我們具體要實現的內容
19             }
20         });
21     }
22 }

 

怎么樣,容易理解吧。未來我們一定還會遇到各種各樣奇葩的說辭,需要你多實踐,透過表象看其本質,這樣就不能輕易的被迷惑了。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM