似たような機能を持っているけれど少しずつ違うクラスを作りたい、という時にはクラスの継承を考えます。継承とはあるクラスをもとに別のクラスを定義する事です。もとになるクラスを継承元クラスまたはスーパークラス、継承され新たに作られたクラスを継承先クラスまたはサブクラスと呼びます。
継承とは
日本語では「受け継ぐこと」「引き継ぐこと」を意味して、法律では「権利や義務を引き継ぐ」という意味で使われます。Javaでも継承元の変数やメソッドを引き継ぐことを意味します。英語でextendという動詞を使っています。キーワードとしてはextendsと最後にsが付いています。これは英語の動詞の三人称単数の変化をしている意味になります。
似たようなクラスが複数あるときは同じ処理を継承元で、違う処理を継承先で行うようにします。
継承関係を作る
似たような二つのクラス、ライオンクラスとラクダクラスがあります。
public class Lion { public String getKind(){ return "動物"; } public String getName(){ return "ライオン"; } public int getSpeed(){ return 70; } }
public class Camel { public String getKind(){ return "動物"; } public String getName(){ return "ラクダ"; } public int getSpeed(){ return 40; } }
これを実行するmainメソッドを持つクラスです。
public class AnimalTest { public static void main(String[] args){ Lion lion = new Lion(); System.out.println("私は" + lion.getName() + "、" + lion.getKind() + "です。"); System.out.println("時速" + lion.getSpeed() + "kmで走ります。"); Camel camel = new Camel(); System.out.println("私は" + camel.getName() + "、" + camel.getKind() + "です。"); System.out.println("時速" + camel.getSpeed() + "kmで走ります。"); } }
実行結果は
$ javac AnimalTest.java $ java AnimalTest 私はライオン、動物です。 時速70kmで走ります。 私はラクダ、動物です。 時速40kmで走ります。
となります。
ライオンもラクダも動物なのは同じで二つのクラスでgetKindの処理は全く同じです。次に動物クラスを作り、これをライオンクラスとラクダクラスが継承するようにします。
public class Animal { public String getKind(){ return "動物"; } }
public class Lion extends Animal { public String getName(){ return "ライオン"; } public int getSpeed(){ return 70; } }
public class Camel extends Animal { public String getName(){ return "ラクダ"; } public int getSpeed(){ return 40; } }
動物クラスにgetKindメソッドを書いて、その代わりライオンクラスとラクダクラスの二つの継承先クラスからはそのメソッドを外しました。二つの継承先にはクラス名のあとにextends Animalという記述を追加しました。これで動物クラスの持っている機能をあたかも自分のもののように使えるようになります。この場合自分のクラスでは定義していないgetKindメソッドを自分のメソッドのように使える事になります。
実行クラスは変更しません。実行すると結果は継承関係を作る前と同じになります。
継承のメリット
継承を使うメリットとはなんでしょうか?
例えばgetKindメソッドで返している「動物」という文字列を「哺乳類」と変更する場合を考えます。継承関係があれば動物クラス一箇所を変更すればよいのですが継承関係のない前のコードでは二箇所の変更が必要になります。
二箇所なら大した事がないとも言えますが同じようなクラスが10個、20個あったらどうでしょう。すべてを変更するのはかなり面倒です。それに変更し忘れや間違いも起こってしまうでしょう。
変更後にちゃんと変更されたか確認するときも継承関係のないケースだとすべてのクラスのgetKindメソッドを確認しなければいけません。しかし継承関係がある場合は例えばライオンクラスで確認すれば他の確認は必要ありません。なぜかというとラクダクラスでもその他のクラスでも同じ動物クラスのgetKindメソッドを利用することがあらかじめわかっているからです。