##継承
前回はAndroidのアプリケーションを模して、擬似的にActivityクラスを作成し、onCreate()などのメソッドを実装し、ライフサイクルの動きを模してみました。実際のAndroidアプリケーションはActivityを継承した形で記述します。継承とは元になるクラスを変更すること無く、そのクラスを拡張するためのJavaの構文です。
通常のAndroidアプリケーションはActivityを継承して自分独自のActivityを作成していきます。例えばActivityを継承したMyAppActivityを作成する場合は次のようにextendsというキーワードを利用し定義します。
public class MyAppActivity extends Activity{
}
このとき、Activityを親クラス(スーパークラス)と呼び、MyAppActivityを子クラス(サブクラス)と呼びます。MyAppActivityに何も記述していない場合、このクラスはActivityクラスと同等のものになります。継承関係があるために、Andorid OSなど呼び出し側のシステムは呼び出すものがActivityであるという認識だけで処理を進めることができます。つまり模擬的なAndroid OSを示す、mainメソッドがあるHelloWorldを次のように記述することがでるのです。
public class HelloWorld {
static public void main(String [] args) {
Activity actA = new MyAppActivity();
actA. message = "おはようございます" ;
actA.onCreate();
}
}
##ポリモーフィズム
重要なのはActivityを継承したアプリケーションはすべてAcitivityとして振る舞うことができるということです。
Activity actA = new MyAppActivity();
の部分に注目してください。右辺は個別のActivityを継承したMyAppActivityですが、左辺はActivityであり、その後の処理には一切変更を加えなくても良いのです。このようにコードを変更すること無く、オブジェクトの振る舞いがさまざまに変わることを、多態性(ポリモーフィズム)と言います。
さて上記の例ではactAのonCreate()を実行しています。MyAppActivityにはonCreate()メソッドが記述されていないため、親クラスのonCreate()が実行され、
onCreateです
おはようございます
のように出力されています。
##メソッドのオーバーライド
実際のAndroidアプリケーションプロジェクトを作成するとActivityを継承したクラスが作成され、onCreate()メソッドが記述されています。そこでMyAppActivityにもonCrate()メソッドを記述してみましょう。
public class MyAppActivity extends Activity{
void onCreate() {
System. out.println( "MyAppActivityのonCreateです" );
}
}
このように記述し、実行すると、
MyAppActivityのonCreateです
と出力されます。つまりAndroid OSなどのシステムが利用しているメソッドを再定義することで、自分独自の振る舞いに変更することができるのです。このように親クラスに定義されているメソッドを再定義することをオーバーライドと呼びます。オーバーライドを行うことで、システム側のコードを一切変更せずにアプリケーションの振る舞いを変更することができるのです。
##親クラスのメソッドの呼び出し
オーバーライドを行うことで、自分のアプリケーション独自の振る舞いを記述することができるようになりますが、親クラスの同じ名前のメソッドは呼び出されなくなります。もしかしたら親クラスの同じ名前のメソッドで重要な処理を行っているかもしれません。そのような場合は、次のように親クラスのメソッドを呼び出すことができます。
void onCreate() {
super.onCreate();
System. out.println( "MyAppActivityのonCreateです" );
}
今の場合、親クラスはActivityクラスです。親クラス(スーパークラス)を呼び出すときはsuperというキーワードを利用します。super常に親クラスを示し、今の場合、Activityを示します。そしてsuper.onCreate()を記述することで親クラスのonCreate()を実行することができます。
本物のAndroidプロジェクトを生成した時に出力されるonCreate()は以下のとおりです。
@Override
protected void onCreate (Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
}
若干異なる部分ありますが、本質的なことは上記のとおりでで、継承とオーバーライドを行うことで、システムはアプリケーションの中身を意識すること無く、Activityとして実行できるのです。
##アノテーション
ここで@Overrideについて解説しましょう。オーバーライドとなるためには基本的に親クラスのメソッドと同じ名前、引数のリスト、戻り値の型でなければなりません。仮にonCreate()メソッドを記述しようと思って、onCraete()と記述してしまったとします。aとeが逆になっているために、オーバーライドとはみなされず、ただのメソッドになってしまいます。このonCraete()メソッドはmain()メソッド内など呼び出しに利用していないため、親クラスのonCreate()メソッドが呼び出されます。
困ったことに、これはこれれでJavaとしては正しい動作なのです。スペルミスをしたがためにエラーも出ずに原因が分からず、思ったような動作をしなくなるのです。このような問題を解決するために、アノテーションという仕組みが用意されました。アノテーションは@から始める目印です。コンパイル時にこの目印を元にプログラムをチェックしてくれます。
@Overrideアノテーションは記述したメソッドが本当にオーバーライドしているのかチェックしてくれます。@Overrideが無くてもプログラムは動きますが、上記のような問題が発生する場合があります。@Overrideを記述し、親クラスにそのメソッドが無い場合はコンパイルエラーとなり教えてくれるのです。