2012年2月4日土曜日

[Java] thisとは #2

What is "this" #2

AndroidアプリケーションのJavaソースにthisを使うことがよくあります。
たとえばToastです。

Main.java(Activity)

ToastクラスのmakeTextメソッドにthisを渡しています。
thisはインスタンス化されたクラス自信です。
このソースはMainクラスの中のthisなので、インスタンス化されたMainクラス自身ということになります。

・なぜmakeTextメソッドにthisを書くのか?
Toastクラスのリファレンスを見てみます。
http://developer.android.com/intl/ja/reference/android/widget/Toast.html
makeTextメソッドの説明にはこう書かれてます。
makeText(Context context, CharSequence text, int duration)
Android-SDKをインストールしたeclipseならマウスをメソッドにホバーするとリファレンスが表示されます。

1壱番目の引数はContextを渡すことになってます。

上のサンプルでmakeTextメソッドに渡したのはContextクラスではなくMainクラスのthisです。
正常に動くけど渡すべきクラスが違うように見えます。

・なぜMainクラスのthisで動くのか?
上のサンプルのMainクラスは次のように定義しています。
public class Main extends Activity
MainクラスはActivityクラスを継承しています。
はActivityクラスのリファレンスを見てみます。
http://developer.android.com/intl/ja/reference/android/app/Activity.html
ここにはこんなことが書かれてます。

java.lang.Object
android.content.Context
android.content.ContextWrapper
android.view.ContextThemeWrapper
android.app.Activity
Activityがどのクラスを継承しているかを説明しています。

ActivityクラスはContextThemeWrapperクラスを継承したサブクラスで
ContextThemeWrapperクラスはContextWrapperクラスを継承したサブクラスで
ContextWrapperクラスはContextクラスを継承したサブクラスです。

つまりMainクラスはContextクラスを継承しているのでContextクラスとして振る舞うことができるのです。
makeTextメソッドに渡したthisはContextクラスを継承したMainクラスだからToastが正常に表示されたわけです。
ServiceクラスもContextクラスを継承しています。
http://developer.android.com/intl/ja/reference/android/app/Service.html
ServiceクラスもでToastを表示するときもmakeTextメソッドにthisを渡します。

・Contextのサブクラス以外のthis
Android-SDKのApiDemosのRotationVectorDemo.javaにこんなコードがあります。

mSensorManager.registerListener(this, mRotationVectorSensor, 10000);

registerListenerメソッドの第1引数はSensorEventListenerインターフェイスを渡すことになってます。
このMyRendererクラスの定義です。
class MyRenderer implements GLSurfaceView.Renderer, SensorEventListener
MyRenderer クラスはSensorEventListenerインターフェイスを継承しています。
SensorEventListenerインターフェイスを継承したクラスのthisはSensorEventListenerとして振る舞うのでregisterListenerメソッドに渡せば動作するわけです。

前回の [Java] thisとは で書ききれなかったAndroidアプリケーションのソースのthisについての説明でした。

以上、参考になれば幸いです。

0 件のコメント:

コメントを投稿