由最簡單的例子理解介面的例項化和麵向介面程式設計
阿新 • • 發佈:2019-01-01
主要寫寫自己對介面例項化的理解:關於介面大家應該都清楚,類實現介面必須實現介面的所有方法,屬性除外。那麼既然有類來例項化介面,那麼為什麼還要把類的例項轉換為介面,也就是我們所說的介面的例項化。這樣一來一回豈不是多此一舉,自找麻煩?
其實面向物件的概念裡面推薦的一條就是面向介面程式設計,拿到介面的例項,我們不必關注類方法具體實現的細節,面向介面程式設計可以降低程式之間的耦合度,是指說在具體的呼叫處都是介面去進行的,並不依賴於具體的某一個類。
比如說定義了個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)。
- 沒多少內容,都是自己的理解,學習理解好面向介面程式設計,對專案程式的擴充套件性和架構都是很重要的,有什麼錯誤的地方還望多多給我留言了。下一篇寫寫具體怎麼在專案中來用的。