1Android的类别继承与委托之范例.docx
《1Android的类别继承与委托之范例.docx》由会员分享,可在线阅读,更多相关《1Android的类别继承与委托之范例.docx(18页珍藏版)》请在冰点文库上搜索。
1Android的类别继承与委托之范例
11.Android的类别继承与委托之范例
1.1类别继承的副作用
继承和委托皆能达到对象再用之目的,各有所长各有所短,相辅相成才是完美的。
如下述类别:
在NewCollegiate字典上对「正方形」的定义是:
「正方形是一种4边等长的长方形」
所以使用继承如下:
然而,上述的实作继承却有些缺点,宜避免之。
例如,Square从Rectangle继承了setLength()和setWidth()函数,但这两个函数对于Square而言是无意义且有害的。
因之,上述的继承关系是不良的。
至于如何改善上述的继承关系呢?
可改用委托:
当Square之对象接到外界传来的area()讯息时,就委托Rectangle之对象代为处理。
虽然委托会令程序复杂些,但勉强使用继承,后遗症将更大。
因为副作用可能会延续到Rectangle的各子孙类别!
1.2Android的继承与委托之例
兹以Android里的MediaPlayer类别为例。
1.2.1操作情境:
1.此程序开始执行后,出现画面如下:
2.按下,就开始播放MP3音乐。
3.若按下,就结束播放音乐。
4.若按下,程序就结束了。
1.2.2范例程序
(1):
采单纯继承方法
1.2.2.1撰写步骤:
Step-1:
建立Android项目:
Px01。
Step-2:
撰写Activity的子类别:
ac01,其程序代码如下:
/*ac01.java*/
packagecom.misoo.pkzz;
importandroid.app.Activity;
importandroid.graphics.Color;
importandroid.media.MediaPlayer;
importandroid.os.Bundle;
importandroid.view.View;
importandroid.view.View.OnClickListener;
importandroid.widget.LinearLayout;
importandroid.widget.TextView;
publicclassac01extendsActivityimplementsOnClickListener{
privatefinalintWC=LinearLayout.LayoutParams.WRAP_CONTENT;
privatefinalintFP=LinearLayout.LayoutParams.FILL_PARENT;
privateMediaPlayermPlayer;
privatemyButtonbtn,btn2,btn3;
publicTextViewtv;
publicvoidonCreate(Bundleicicle){
super.onCreate(icicle);
LinearLayoutlayout=newLinearLayout(this);
layout.setOrientation(LinearLayout.VERTICAL);
btn=newmyButton(this);
btn.setId(101);
btn.setText("play");
btn.setOnClickListener(this);
LinearLayout.LayoutParamsparam=
newLinearLayout.LayoutParams(btn.get_width(),
btn.get_height());
param.topMargin=10;
layout.addView(btn,param);
btn2=newmyButton(this);
btn2.setId(102);
btn2.setText("stop");
btn2.setOnClickListener(this);
layout.addView(btn2,param);
btn3=newmyButton(this);
btn3.setId(103);
btn3.setText("exit");
btn3.setOnClickListener(this);
layout.addView(btn3,param);
tv=newTextView(this);
tv.setTextColor(Color.WHITE);
tv.setText("Ready");
LinearLayout.LayoutParamsparam2=
newLinearLayout.LayoutParams(FP,WC);
param2.topMargin=10;
layout.addView(tv,param2);
setContentView(layout);
//---------------------------------------
myMediaPlayermy_player=newmyMediaPlayer();
mPlayer=my_player.create(this,R.raw.test_cbr);
}
publicvoidonClick(Viewv){
switch(v.getId()){
case101:
mPlayer.start();
break;
case102:
mPlayer.stop();
break;
case103:
finish();
break;
}
}
}
Step-3:
撰写myMediaPlayer类别,其程序代码如下:
/*myMediaPlayer.java*/
packagecom.misoo.pkzz;
importandroid.content.Context;
importandroid.media.MediaPlayer;
publicclassmyMediaPlayerextendsMediaPlayer{
publicstaticMediaPlayercreate(Contextcontext){
returnMediaPlayer.create(context,R.raw.test_cbr);
}
}
Step-4:
撰写Button的子类别:
myButton,其程序代码如下:
/*myButton.java*/
packagecom.misoo.pkcc;
importandroid.content.Context;
importandroid.widget.Button;
publicclassmyButtonextendsButton{
publicmyButton(Contextctx){
super(ctx);
super.setBackgroundResource(R.drawable.heart);
}
publicintget_width(){
return80;
}
publicintget_height(){
return50;
}
}
Step-5:
执行之。
1.2.2.2说明:
在ac01类别的指令:
myMediaPlayermy_player=newmyMediaPlayer();
mPlayer=my_player.create(this,R.raw.test_cbr);
所传回来的是MediaPlayer类别之对象参考(即mPlayer的值),而不是myMediaPlayer类别的对象参考。
既然是MediaPlayer类别之对象参考,则外界的类别或函数(如ac01类别)就能透过mPlayer参考(即使用MediaPlayer接口)来使用此新诞生的MediaPlayer类别之对象了,如下图:
虽然在my_player对象里也有一个MediaPlayer的小对象,但是mPlayer并不是参考到它,而是参考到由create()函数所诞生的心对象。
1.2.3范例程序
(2):
采继承与委托混合型
1.2.3.1 撰写步骤:
Step-1:
建立Android项目:
Px02。
Step-2:
撰写Activity的子类别:
ac01,其程序代码如下:
/*ac01.java*/
packagecom.misoo.pkzz;
importandroid.app.Activity;
importandroid.graphics.Color;
importandroid.os.Bundle;
importandroid.view.View;
importandroid.view.View.OnClickListener;
importandroid.widget.LinearLayout;
importandroid.widget.TextView;
publicclassac01extendsActivityimplementsOnClickListener{
privatefinalintWC=LinearLayout.LayoutParams.WRAP_CONTENT;
privatefinalintFP=LinearLayout.LayoutParams.FILL_PARENT;
privatemyMediaPlayermy_player;
privatemyButtonbtn,btn2,btn3;
publicTextViewtv;
publicvoidonCreate(Bundleicicle){
super.onCreate(icicle);
LinearLayoutlayout=newLinearLayout(this);
layout.setOrientation(LinearLayout.VERTICAL);
btn=newmyButton(this);
btn.setId(101);
btn.setText("play");
btn.setOnClickListener(this);
LinearLayout.LayoutParamsparam=
newLinearLayout.LayoutParams(btn.get_width(),
btn.get_height());
param.topMargin=10;
layout.addView(btn,param);
btn2=newmyButton(this);
btn2.setId(102);
btn2.setText("stop");
btn2.setOnClickListener(this);
layout.addView(btn2,param);
btn3=newmyButton(this);
btn3.setId(103);
btn3.setText("exit");
btn3.setOnClickListener(this);
layout.addView(btn3,param);
tv=newTextView(this);
tv.setTextColor(Color.WHITE);
tv.setText("Ready");
LinearLayout.LayoutParamsparam2=
newLinearLayout.LayoutParams(FP,WC);
param2.topMargin=10;
layout.addView(tv,param2);
setContentView(layout);
//---------------------------------------
my_player=myMediaPlayer.create(this);
}
publicvoidonClick(Viewv){
switch(v.getId()){
case101:
my_player.start();
break;
case102:
my_player.stop();
break;
case103:
finish();
break;
}
}
}
Step-3:
撰写myMediaPlayer类别,其程序代码如下:
/*myMediaPlayer.java*/
packagecom.misoo.pkzz;
importandroid.app.Activity;
importandroid.content.Context;
importandroid.media.MediaPlayer;
importandroid.util.Log;
publicclassmyMediaPlayerextendsMediaPlayer{
privatestaticMediaPlayermSuper;
privatestaticContextctx;
publicstaticmyMediaPlayercreate(Contextcontext){
ctx=context;
mSuper=MediaPlayer.create(context,R.raw.test_cbr);
returnnewmyMediaPlayer();
}
publicvoidstart(){
try{
mSuper.start();
((ac01)ctx).tv.setText("Playingaudio...");
((Activity)ctx).setTitle("MP3Music");
}catch(Exceptione){
Log.e("StartPlay","error:
"+e.getMessage(),e);
}
}
publicvoidstop(){
if(mSuper!
=null){
((ac01)ctx).tv.setText("Stop");
mSuper.stop();
mSuper.release();
mSuper=null;
}
}
}
Step-4:
撰写Button的子类别:
myButton,其程序代码如下:
/*myButton.java*/
packagecom.misoo.pkcc;
importandroid.content.Context;
importandroid.widget.Button;
publicclassmyButtonextendsButton{
publicmyButton(Contextctx){
super(ctx);
super.setBackgroundResource(R.drawable.heart);
}
publicintget_width(){
return80;
}
publicintget_height(){
return50;
}
}
Step-5:
执行之。
1.2.3.2 说明:
在ac01对象里的my_player是参考到myMediaPlayer的对象,此对象里mSuper再参考到MediaPlayer的对象,如下图:
在ac01类别里的指令:
my_player.start();
是呼叫到myMediaPlayer子类别的start()函数,然后才委托呼叫MediaPlayer的start()函数。
此时,可看到「继承的副作用」了,就是:
myMediaPlayer继承了众多函数,并无法透过my_palyer去呼叫之,甚至可能是有害的。
因此宜改用下一小节的单纯委托方法。
1.2.4范例程序(3):
采单纯委托方法
1.2.4.1 撰写步骤:
Step-1:
建立Android项目:
Px03。
Step-2:
撰写Activity的子类别:
ac01,其程序代码如下:
/*ac01.java*/
packagecom.misoo.pkcc;
importandroid.app.Activity;
importandroid.graphics.Color;
importandroid.os.Bundle;
importandroid.view.View;
importandroid.view.View.OnClickListener;
importandroid.widget.LinearLayout;
importandroid.widget.TextView;
publicclassac01extendsActivityimplementsOnClickListener{
privatefinalintWC=LinearLayout.LayoutParams.WRAP_CONTENT;
privatefinalintFP=LinearLayout.LayoutParams.FILL_PARENT;
privatemp3Playermp3_player;
privatemyButtonbtn,btn2,btn3;
publicTextViewtv;
publicvoidonCreate(Bundleicicle){
super.onCreate(icicle);
mp3_player=newmp3Player(this);
LinearLayoutlayout=newLinearLayout(this);
layout.setOrientation(LinearLayout.VERTICAL);
btn=newmyButton(this);
btn.setId(101);
btn.setText("play");
btn.setOnClickListener(this);
LinearLayout.LayoutParamsparam=
newLinearLayout.LayoutParams(btn.get_width(),
btn.get_height());
param.topMargin=10;
layout.addView(btn,param);
btn2=newmyButton(this);
btn2.setId(102);
btn2.setText("stop");
btn2.setOnClickListener(this);
layout.addView(btn2,param);
btn3=newmyButton(this);
btn3.setId(103);
btn3.setText("exit");
btn3.setOnClickListener(this);
layout.addView(btn3,param);
tv=newTextView(this);
tv.setTextColor(Color.WHITE);
tv.setText("Ready");
LinearLayout.LayoutParamsparam2=
newLinearLayout.LayoutParams(FP,WC);
param2.topMargin=10;
layout.addView(tv,param2);
setContentView(layout);
}
publicvoidonClick(Viewv){
switch(v.getId()){
case101:
mp3_player.start();break;
case102:
mp3_player.stop();break;
case103:
finish();break;
}
}
}
Step-3:
撰写mp3Player类别,其程序代码如下:
/*mp3Player.java*/
packagecom.misoo.pkcc;
importandroid.app.Activity;
importandroid.content.Context;
importandroid.media.MediaPlayer;
importandroid.util.Log;
publicclassmp3Player{
privateMediaPlayermPlayer;
privateContextctx;
publicmp3Player(Contextcontext){
ctx=context;
mPlayer=MediaPlayer.create(ctx,R.raw.test_cbr);
}
publicvoidstart(){
try{
mPlayer.start();
((ac01)ctx).tv.setText("Playingaudio...");
((Activity)ctx).setTitle("MP3Music");
}catch(Exceptione){
Log.e("StartPlay","error:
"+e.getMessage(),e);
}
}
publicvoidstop(){
if(mPlayer!
=null){
((ac01)ctx).tv.setText("Stop");
mPlayer.stop();
mPlayer.release();
mPlayer=null;
}
}
}
Step-4:
撰写Button的子类别:
myButton,其程序代码如下:
/*myButton.java*/
packagecom.misoo.pkcc;
importandroid.content.Context;
importandroid.widget.Button;
publicclassmyButtone