クラスを継承する – extendsキーワード
[modifier] class name extends sname {
definition
}
modifier:修飾子
name:サブクラスの名前
sname:スーパークラスの名前
definition:メンバーの定義
継承(Inheritance)とは、あるクラスの機能を引き継ぎながら新しいクラスを定義することを言います。継承元となるクラスのことスーパークラス、継承の結果できた新しいクラスのことをサブクラスと言います。
継承には、クラスを定義する際にextendsキーワードを付けて継承元を指定します。一度に複数のクラスをまとめて継承することはできませんので注意してください(多重継承の禁止)。
たとえば以下は、Animalクラスを継承したHamsterクラスを定義する例です。以下では、Hamster独自のgnaw(齧る)メソッドを追加しています。
Hamster.java
- class Hamster extends Animal {
- public Hamster(String name, String color) {
- super(name, color);
- }
- public void gnaw() {
- System.out.println("ガジガジ…");
- }
- }
サブクラスではsuperキーワードを利用することで、スーパークラスのコンストラクターやメソッドを参照できます。上の例であれば「super(name, color)」の部分です。
もしもスーパークラスのメソッドを呼び出したいならば、以下のようにします。
- super.getInfo("%s:%s");
メソッドのオーバーライド
サブクラスでは、(新しいメソッドを追加するだけでなく)スーパークラスで既に存在するメソッドを上書きすることもできます。これをメソッドのオーバーライドと言います。 もしもサブクラスの側で、メソッドをオーバーライドしてほしくない場合には、スーパークラスのメソッドにfinal修飾子を付与してください。
関連ページ
補足:コンストラクターの挙動
スーパークラスで定義されたメソッドがサブクラスにそのまま引き継がれるのに対して、コンストラクターはそのままでは引き継がれない点に注意してください。
たとえば以下のようなコードは、意図したように動作しません。
- public class SuperClass {
- int value;
- public SuperClass(int value) {
- this.value = value;
- }
- }
- public class SubClass extends SuperClass {
- // コンストラクターを定義しない
- }
この状態で、スーパークラスのコンストラクターが呼び出されることを期待して、「SubClass sub = new SubClass(10);」のようなコードを書くことはできません。先ほども述べたように、コンストラクターはサブクラスには引き継がれないからです。
では、SubClassクラスを、以下のように書き換えてみるとどうでしょう。
- public class SubClass extends SuperClass {
- public SubClass(int value) {
- this.value = value;
- }
- }
この場合、同じくサブクラスをインスタンス化した時点で、「暗黙的スーパー・コンストラクター SuperClass() は未定義です。別のコンストラクターを明示的に呼び出す必要があります」のようなエラーとなります。これは、サブクラスがインスタンス化される際に、暗黙的にスーパークラスの引数なしコンストラクターを呼び出そうとしているために生じるエラーです。
これを避けるために、2つの方法があります。
ひとつは、スーパークラスに引数なしのコンストラクターを指定すること、もうひとつは、サブクラスのコンストラクターで明示的にスーパークラスのコンストラクターを呼び出すことです。
- public SubClass(int value) {
- super(value);
- }
superキーワードで明示的にスーパークラスのコンストラクターを呼び出した場合には、引数なしのコンストラクターは呼び出されなくなりますので、エラーも解消されます。
監修