Java のコンストラクタと継承(親クラスのコンストラクタを呼ぶ方法)を初心者向けにやさしく解説
新人
「Javaでクラスを継承したとき、親クラスの初期設定はどうするんですか?」
先輩
「それはコンストラクタを使うんだ。親クラスの初期化処理を呼びたいときには、superを使うといいよ。」
新人
「superって前にも出てきたキーワードですね!コンストラクタでも使えるんですか?」
先輩
「うん、super()っていう書き方で、親クラスのコンストラクタを呼び出せるんだ。じゃあ、コンストラクタの基本から順番に見ていこう!」
1. コンストラクタってなに?(Javaでの基本)
Javaのコンストラクタとは、クラスからオブジェクトを作ったときに、最初に実行される特別なメソッドです。オブジェクトができた直後に、自動で呼び出されます。
たとえば、「人」を表すクラスがあって、その人の名前を設定したいときに使います。コンストラクタで名前を受け取って、初期設定できるようにしておきます。
public class Person {
String name;
// コンストラクタ(クラス名と同じ)
public Person(String inputName) {
name = inputName;
}
void sayHello() {
System.out.println("こんにちは、" + name + "です。");
}
}
このように、クラスの名前と同じ名前のメソッドを作ると、それがコンストラクタになります。戻り値は書かなくてOKです。
そして、このPersonクラスを使ってオブジェクトを作ると、コンストラクタが自動で呼び出されます。
public class Main {
public static void main(String[] args) {
Person p = new Person("タナカ");
p.sayHello();
}
}
こんにちは、タナカです。
このように、コンストラクタはオブジェクトの初期設定をするための仕組みなのです。
2. 親クラスと子クラスの関係を簡単におさらい
Javaでは、継承という仕組みを使って、すでにあるクラス(親クラス)から別のクラス(子クラス)を作ることができます。親クラスに共通の処理を書いておくと、子クラスで再利用できます。
たとえば、「動物」を表すクラスがあって、「犬」や「猫」などのクラスがそれを継承するというイメージです。
public class Animal {
void move() {
System.out.println("動きます。");
}
}
public class Dog extends Animal {
void bark() {
System.out.println("ワンワン!");
}
}
このように、DogクラスはAnimalクラスを継承しています。なので、Dogクラスは親であるAnimalのmove()メソッドもそのまま使えます。
public class Main {
public static void main(String[] args) {
Dog dog = new Dog();
dog.move(); // 親クラスのメソッド
dog.bark(); // 子クラスのメソッド
}
}
動きます。
ワンワン!
このように、Javaの継承を使えば、親クラスの機能をそのまま使えるだけでなく、必要に応じて子クラスで追加や変更もできます。
このあと紹介する「親クラスのコンストラクタを呼ぶ方法」も、Javaの継承と初期設定をうまく組み合わせるための大切な考え方です。
3. 親クラスのコンストラクタは自動で呼ばれるの?
Javaでは、子クラスのオブジェクトを作るとき、親クラスのコンストラクタが自動で呼び出されます。ただし、それは「引数のないコンストラクタ」が親クラスにある場合だけです。
たとえば、親クラスに何も書かなかったとしても、Javaが自動で空のコンストラクタを用意してくれます。これを「デフォルトコンストラクタ」と呼びます。
public class Parent {
public Parent() {
System.out.println("親クラスのコンストラクタ");
}
}
public class Child extends Parent {
public Child() {
System.out.println("子クラスのコンストラクタ");
}
}
public class Main {
public static void main(String[] args) {
Child c = new Child();
}
}
親クラスのコンストラクタ
子クラスのコンストラクタ
このように、super()と書かなくても、Javaが自動で親の引数なしコンストラクタを呼んでくれます。
4. super()を使って親のコンストラクタを明示的に呼ぶ
Javaで親クラスのコンストラクタを自分で明示的に呼びたいときは、super()を使います。これは子クラスのコンストラクタの一番最初の行に書く必要があります。
このとき呼ばれるのは、親クラスの「引数なしのコンストラクタ」です。
public class Parent {
public Parent() {
System.out.println("親の初期設定");
}
}
public class Child extends Parent {
public Child() {
super();
System.out.println("子の初期設定");
}
}
public class Main {
public static void main(String[] args) {
Child c = new Child();
}
}
親の初期設定
子の初期設定
super()を使うことで、「この子クラスは親のコンストラクタをちゃんと使ってますよ」とJavaに伝えることができます。
5. 親コンストラクタに引数がある場合はどうする?
もし親クラスのコンストラクタに引数がある場合は、super()の中にその引数を渡す必要があります。自動では呼び出されません。
たとえば、親クラスで名前を受け取るようにした場合は、子クラスのコンストラクタでsuper("名前")のように書きます。
public class Parent {
String name;
public Parent(String n) {
name = n;
System.out.println("親の名前: " + name);
}
}
public class Child extends Parent {
public Child(String n) {
super(n);
System.out.println("子のコンストラクタ完了");
}
}
public class Main {
public static void main(String[] args) {
Child c = new Child("タナカ");
}
}
親の名前: タナカ
子のコンストラクタ完了
このように、親クラスに引数がある場合は、必ず子クラスからもその値を渡すようにしておかないとエラーになります。
このようなルールを覚えておくと、Javaの継承とコンストラクタの関係がスムーズに理解できるようになります。
6. 子クラスと親クラスのコンストラクタをうまく使い分けよう
Javaでは、子クラスと親クラスのコンストラクタをうまく使い分けることで、コードが見やすくなり、ミスも減ります。
たとえば、親クラスが共通の初期設定を行い、子クラスでは独自の初期設定を行うといった使い方ができます。
public class Animal {
String type;
public Animal(String type) {
this.type = type;
System.out.println("動物の種類: " + type);
}
}
public class Cat extends Animal {
String name;
public Cat(String type, String name) {
super(type);
this.name = name;
System.out.println("猫の名前: " + name);
}
}
public class Main {
public static void main(String[] args) {
Cat cat = new Cat("ネコ科", "ミケ");
}
}
動物の種類: ネコ科
猫の名前: ミケ
このように、親クラスの共通部分はsuper()で渡し、子クラスの追加部分は自分で設定するという考え方です。
7. よくあるミスとエラー例(super()の位置・書き忘れ)
Javaでコンストラクタを使うときに初心者がよくやってしまうミスがあります。とくに注意したいのがsuper()の位置と書き忘れです。
1つ目はsuper()の位置が間違っているパターンです。super()はコンストラクタの1行目でなければなりません。
// 間違った例(コンパイルエラーになる)
public class Dog extends Animal {
public Dog() {
System.out.println("犬の初期設定");
super(); // ←これはダメ!
}
}
このように、super()より先に何かを書くとエラーになります。
2つ目は、親クラスに引数ありコンストラクタがあるのに、super()を書かないパターンです。
public class Animal {
public Animal(String type) {
System.out.println("動物の種類: " + type);
}
}
public class Dog extends Animal {
public Dog() {
// super("イヌ科"); を書き忘れている → エラー!
System.out.println("犬の初期設定");
}
}
このように、親に引数が必要なら、必ずsuper()で渡す必要があります。
8. 初心者に伝えたいコンストラクタ設計のコツ
最後に、Javaのコンストラクタ設計のコツを初心者向けにまとめます。
1. 共通処理は親クラスに書こう
複数のクラスで同じような初期設定が必要なら、親クラスに書いておくと再利用しやすくなります。
2. 子クラスでは必要に応じてsuper()を使う
親クラスに初期化の処理があるなら、super()でしっかり呼び出してあげましょう。
3. コンストラクタが増えてきたら整理しよう
同じクラスに複数のコンストラクタがあるときは、コードが読みにくくなるので、コメントを書いたり、処理を分けるのがおすすめです。
4. まずは簡単な例から慣れる
最初はsuper()だけを使って、親のメッセージを表示するだけの簡単なコードから試してみましょう。
Javaの継承とコンストラクタをうまく組み合わせることで、コードをスッキリ整理しながら、使いやすいクラス設計ができるようになります。