[#0x0018] 对内部类的继承

  首先我们要搞清楚关于closure这个单词的逻辑关系。如果说内部类是一个closure,那么外部类就是enclosing class,because OuterClass encloses InnerClass。

 

  如果一个一般类来继承内部类,需要在构造器中使用特殊的语法。

class Outer
{
	class Inner {}
}

public class ExtInner extends Outer.Inner
{
	public ExtInner(Outer o)
	{
		o.super();
	}
}

  ExtInner的构造器必须要有一个Outer参数,然后调用.super();。这里要求必须使用一个enclosingClassReference.super();。

  你可能会问:在ExtInner的构造器里return o.new Inner();行不行?编译器会告诉你:constructor返回的还是void。这个是本话题的意外收获。

  然后ExtInner中无法通过Outer.this来连接到外部类对象,在ExtInner中使用Outer.this会得到编译错误“Outer不是封闭类”(Java SE 1.5.0_15),这里的封闭类应该就是enclosing class的意思,“Outer不是封闭类”表示Outer并没有enclose ExtInner,虽然Outer有enclose Inner,且ExtInner继承自Inner。

 

  如果Base有一个Inner,然后Ext继承了Base,这时Ext并没有继承Base.Inner的代码,即Base.Inner的代码没有复制到Ext中。此时,如果在Ext中也写一个Inner,其实是不会发生冲突的。

 

  如果内部类、外部类双重继承,情况如何呢?看下面代码:

class BaseOuter
{
	void print()
	{
		System.out.println("BaseOuter prints");
	}
	
	class BaseInner
	{
		void print2()
		{
			System.out.println("BaseInner prints");
		}
		
		void print3()
		{
			BaseOuter.this.print();
		}
	}
}

class ExtOuter extends BaseOuter
{
	void print4()
	{
		System.out.println("ExtOuter prints");
	}
	
	class ExtInner extends BaseOuter.BaseInner
	{
		void print5()
		{
			System.out.println("ExtInner prints");
		}
		
		void print6()
		{
			ExtOuter.this.print4();
		}
		
		void print7()
		{
			BaseOuter.this.print(); //error: BaseOut is not the enclosing class
		}
	}
}

public class ExtInnerTest
{
	public static void main(String[] args)
	{
		ExtOuter eo = new ExtOuter();
		ExtOuter.ExtInner ei = eo.new ExtInner();
		
		ei.print2();
		ei.print3();
		ei.print5();
		ei.print6();
		ei.print7(); //error: BaseOut is not the enclosing class
	}
}

  可以看到ExtInner可以通过向上转型变成BaseInner,然后再连接到BaseOut.this("ei.print3();"通过编译并运行),但是不能直接使用BaseOut.this("ei.print7();" won't compile)。

 

  总结一点,内部类不能被外部类的导出类继承,外部类也不enclose内部类的导出类。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
在 MusicActivity.java 添加组件 private Button startButton ; private Button pauseButton ; private SeekBar seekbar ; private boolean isBound = false ; private PlayService playService ; private static final String TAG = ” MusicActivity ” ; private final int MUSICDURATION = 0x1 ; //获 取 歌 曲 播 放 时 间 标 志 private final int UPDATE = 0x2 ; //更 新 进 度 条 标 志 • 让 MusicActivity 实现 View.OnClickListener,SeekBar.OnSeekBarChangeListener 两个接口,这样 该 Activity 同时也变成了监听类 • 创建后台 PlayService.java, 并让它继承 Service 类,实现 MediaPlayer.OnCompletionListener 接口, 并添加成员 MediaPlayer mediaPlayer; • 在 PlayService 类添加几个方法以控制 MediaPlayer 的状态转移 public void play ( ) { try { mediaPlayer . r e s e t ( ) ; mediaPlayer . prepare ( ) ; mediaPlayer . s t a r t ( ) ; } catch ( IOException e ) { e . printStackTrace ( ) ; } } public void pause ( ) { mediaPlayer . pause ( ) ; i s P l a y i n g = false ; } public void s t a r t ( ) { mediaPlayer . s t a r t ( ) ; i s P l a y i n g = true ; } public void setTo ( int msec ) { mediaPlayer . seekTo ( msec ) ; } public int getDuration ( ) { return duration ; } public MediaPlayer getMediaPlayer ( ) { return mediaPlayer ; } @Override public void onCompletion ( MediaPlayer mp) { i s P l a y i n g = false ; } • 重构 onBind 方法,并添加一个 Binder 内部类能够在外部获取 Service 的实例 @Override public IBinder onBind ( Intent i n t e n t ) { return new PlayBinder ( ) ; 3 4.1 实训步骤 《Android 应用程序开发》广西职业师范学院实验教学指导书 } class PlayBinder extends Binder { public PlayService getPlayService ( ) { return PlayService . this ; } } • 其他方法一览 @Override public void onCreate ( ) { super . onCreate ( ) ; try { mediaPlayer = MediaPlayer . c r e a t e ( this , R. raw . sleepaway ) ; mediaPlayer . setOnCompletionListener ( this ) ; duration = mediaPlayer . getDuration ( ) ; } catch ( Exception e ) { e . printStackTrace ( ) ; } } private Runnable runnable = new Runnable ( ) { @Override public void run ( ) { mediaPlayer . seekTo ( mediaPlayer . getCurrentPosition ( ) ) ; } } ; • 将 MusicActivity 与 PlayService 进行整合 //连 接 A c t i v i t y 和
06-02

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值