通过Android View的两种事件响应方法比较inheritance和composition

发布时间:2017-3-31 2:24:06 编辑:www.fx114.net 分享查询网我要评论
本篇文章主要介绍了"通过Android View的两种事件响应方法比较inheritance和composition",主要涉及到通过Android View的两种事件响应方法比较inheritance和composition方面的内容,对于通过Android View的两种事件响应方法比较inheritance和composition感兴趣的同学可以参考一下。

Android view有两种主要的处理事件的方式, 在View的子类中覆盖onXXX方法。因为这是在子类中通过覆盖的方式来响应事件,我称之为基于继承(inheritance)的响应方式。 调用View.setXXXListener,参数会实现View.OnXXXListener接口。因为View对象和Listner组合起来完成工作,我称之为基于组合(composition)的响应方式。 例如对于touch事件而言,View.dispatchTouchEvent接收到touch事件对象,然后: 调用通过View.setOnTouchListener注册的listener。 调用可以被子类覆盖的onTouchEvent方法。 举个简单例子,一个Activity中有一个edit框(EditText对象)。EditText是通过代码添加的到Activity中的。我希望在点击它时,自动把该框的底色设置为红色。 如果采用第一种方式,其EditText的子类是: public class TouchChangeBackgroundColorEditText extends EditText { public MyEditText(Context context, AttributeSet attrs) { super(context, attrs); } @Override public boolean onTouchEvent(MotionEvent event) { this.setBackgroundColor(Color.RED); return super.onTouchEvent(event); } } 然后我们在Activity中使用该EditText的子类。 如果采用第二种方法,则需要创建一个对touch事件的listener: public class TouchChangeBackgroundColorListener implements View.OnTouchListener { @Override public boolean onTouch(View v, MotionEvent event) { v.setBackgroundColor(Color.RED); return false; } } 然后在Activity中使用普通EditText,并对该EditText调用setOnTouchListener(new TouchChangeBackgroundColorListener)。 然后用户又想对某些EditText使用Key event来改变背景颜色,那如果采用基于继承的方式,用户需要创建KeyChangeBackGroundColorEditText的子类,在其中覆盖onKeyDown方法;如果采用组合的方式,则需要实现OnKeyListener并添加到EditText中。 现在问题来了,用户希望某些EditText是不响应touch和key事件的,有些只响应一种,有些两种都响应。那么如果采用继承的方式,那需要四种对象,一个基本都EditText和三种针对only touch,only key和both touch and key的子类。 但如果采用组合的方式,我们仍然只需要两个listener,只需对不同的EditText添加不同的listener即可。 如果更复杂,我们还想针对trackball改变颜色,那如果采用继承,则可能有3×3=9种类。但采用组合,只需要三种listener,然后EditText根据需要添加即可。 所以说,在可能有多种因素导致变化的时候,继承可能导致对象种类(即类)爆炸式增长;而组合可以用不同的对象封装不同的变化,减少类的个数。 但这里减少的只是编码中类的个数,而在运行时如果采用继承,那对象的个数是EditText的个数;但如果采用组合,那每个EditText都对应着一个Listener,所以有更多的对象个数。所以说,组合一般较继承产生更多的运行时对象,这需要更多的内存(对象存储)和运算时间(对象间相互调用)。 现在假设app的界面上已经有一个EditText控件,我们又想在app中通过选项来控制该EditText的行为,例如我们有三个选项,分别对应touch,key和trackball事件发生时是否改变该EditText的背景颜色。那么如果采用组合,可以先创建好三个listener,然后根据选择添加listener到现有的的EditText中。但如果使用继承,根本是无法动态改变其行为了。所以说,组合可以动态改变对象的行为,而继承只能在静态改变。 再回到前面继承的onTouchEvent方法,在最后一行,我需要调用super.onTouchEvent。事实上,我开始实现时忘记调用这行了,结果点击edit框时,可以改变颜色,但无法切出输入法。在现实中覆盖父类的方法时,有的父类方法是需要在子类中被调用的,但有的却不需要。覆盖的时候要详细查看父类文档和代码。但如果采用组合的方式,我只需要关系listener自己的视线即可,并不需要调用view中跟touch处理相关的代码。所以说,继承是一种白盒复用,在覆盖父类的方法时,需要关心父类方法的实现;但组合是黑盒测试,我只需要实现接口即可,而不需要关心该接口如何被调用。 故而Design pattern中所有模式的两大基石之一就是:Favor object composition over class inheritance。

上一篇:deque 双端队列容器 学习笔记
下一篇:

相关文章

相关评论

本站评论功能暂时取消,后续此功能例行通知。

一、不得利用本站危害国家安全、泄露国家秘密,不得侵犯国家社会集体的和公民的合法权益,不得利用本站制作、复制和传播不法有害信息!

二、互相尊重,对自己的言论和行为负责。

好贷网好贷款