转载请标明出处: http://blog.csdn.net/programming_snail/article/details/50488121
出自:Panda_Wang_
主要写写自己对接口实例化的理解:关于接口大家应该都清楚,类实现接口必须实现接口的所有方法,属性除外。那么既然有类来实例化接口,那么为什么还要把类的实例转换为接口,也就是我们所说的接口的实例化。这样一来一回岂不是多此一举,自找麻烦?
其实面向对象的概念里面推荐的一条就是面向接口编程,拿到接口的实例,我们不必关注类方法具体实现的细节,面向接口编程可以降低程序之间的耦合度,是指说在具体的调用处都是接口去进行的,并不依赖于具体的某一个类。
比如说定义了个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)。
- 没多少内容,都是自己的理解,学习理解好面向接口编程,对项目程序的扩展性和架构都是很重要的,有什么错误的地方还望多多给我留言了。下一篇写写具体怎么在项目中来用的。