1. 程式人生 > >由最簡單的例子理解介面的例項化和麵向介面程式設計

由最簡單的例子理解介面的例項化和麵向介面程式設計

  • 主要寫寫自己對介面例項化的理解:關於介面大家應該都清楚,類實現介面必須實現介面的所有方法,屬性除外。那麼既然有類來例項化介面,那麼為什麼還要把類的例項轉換為介面,也就是我們所說的介面的例項化。這樣一來一回豈不是多此一舉,自找麻煩?

  • 其實面向物件的概念裡面推薦的一條就是面向介面程式設計,拿到介面的例項,我們不必關注類方法具體實現的細節,面向介面程式設計可以降低程式之間的耦合度,是指說在具體的呼叫處都是介面去進行的,並不依賴於具體的某一個類。
    比如說定義了個I介面,有兩個fun1,fun2方法。然後有三個類實現了該介面:
    I i1 = new A();
    I i2 = new B();
    I i3 = new C();

  • 可以有很多個類實現了該介面,但當我們還沒例項化的時候,我們可以I i直接拿來用,i.fun1,i.fun2可以提前程式設計,我們可以直接對i來進行程式設計設計,具體的取那一種例項由以後需求變化的時候我們自己選擇,我的理解是:這樣的好處叫做提前程式設計,我可以先把這個類(介面的例項),在他還沒例項化的時候拿來用,以後等他具體實現了再給賦例項值,當然這種說法是我自己的理解。
    其實面向介面程式設計用的地方非常多,有時候我們也經常寫,絕對用到他了,只不過沒注意罷了,由最簡單用的最多的地方說說吧。下面是最簡單的一個點選Button事件

import com.example.com.cn.wp.test1.R;
import
android.os.Bundle; import android.app.Activity; import android.view.Menu; import android.view.View; import android.view.View.OnClickListener; import android.widget.Button; import android.widget.Toast; public class MainActivity extends Activity implements OnClickListener{ private Button mBtn1; @Override
protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); mBtn1 = (Button) findViewById(R.id.id_btn1); mBtn1.setOnClickListener(this); } @Override public void onClick(View v) { switch (v.getId()) { case R.id.id_btn1: Toast.makeText(MainActivity.this, "id_btn1", Toast.LENGTH_SHORT).show(); break; default: break; } } }
  • setOnClickListener(this)這是我們經常寫的方法吧,有時候還總會丟掉這句程式碼,來看看原理以後就不會漏了。通過setOnClickListener(this)來給具體的例項化介面賦值,這裡就是剛前面所說的:具體類實現的時候再給他賦值,即this。因為這裡是BUTTON mBtn1呼叫setOnClickListener給他賦值了,那麼我們可以推測並證明一個問題:BUTTON類或BUTTON的父類,肯定是提前用這個介面了,並且呼叫OnClickListener介面的onClick()方法,否則誰知道你點選的OnClick方法了,可以找原始碼來看看:
  • 繼承關係圖層次:Button->TextView->View,在View.class裡面我們找到了,如下:
    //具體OnClickListener介面,就一個方法
    public interface OnClickListener {
        void onClick(View v);
    }
       //介面宣告
        public OnClickListener mOnClickListener;
       //介面的賦值,也就是介面的註冊
       public void setOnClickListener(OnClickListener l) {
        if (!isClickable()) {
            setClickable(true);
        }
        getListenerInfo().mOnClickListener = l;
    }
  • 可以看到先是對isClickable的判斷,這裡先不看,最後將例項賦值給getListenerInfo().mOnClickListener,其中getListenerInfo()是拿到view的一個靜態內部類ListenerInfo的例項,該例項內部就有我們需要知道的mOnClickListener介面,通過介面的例項來掉用OnClick();下面是兩處的呼叫程式碼:
    //具體呼叫OnClick()點選事件的方法
    public boolean performClick() {
        sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_CLICKED);

        ListenerInfo li = mListenerInfo;
        if (li != null && li.mOnClickListener != null) {
            playSoundEffect(SoundEffectConstants.CLICK);
            li.mOnClickListener.onClick(this);
            return true;
        }

        return false;
    } 
    //具體呼叫OnClick()點選事件的方法
    public boolean callOnClick() {
        ListenerInfo li = mListenerInfo;
        if (li != null && li.mOnClickListener != null) {
            li.mOnClickListener.onClick(this);
            return true;
        }
        return false;
    }
  • 這就是提前程式設計了,也就是我們常說的介面回撥,在view類裡面我們就已經通過mOnClickListener.OnClick(this)來呼叫這個方法了,該方法的最終的實現做什麼事是放在了MainActivity的OnClick方法我們具體來實現了,而android的架構師並不知道我們後面怎麼處理,自己先用,以後留給我們去填這個例項,即setOnClickListener(this)。
  • 沒多少內容,都是自己的理解,學習理解好面向介面程式設計,對專案程式的擴充套件性和架構都是很重要的,有什麼錯誤的地方還望多多給我留言了。下一篇寫寫具體怎麼在專案中來用的。