- 公開日: 2018年01月11日
【超初心者向け】Javaの継承について徹底解説
継承(inheritance)は、Javaのようなオブジェクト指向を使ったプログラミングを行う際に大切な考え方の一つです。Javaの学習を始めたばかりの方には、オブジェクト指向の特徴的な書き方や概念が、とても難しく感じられるかもしれません。でも、一度理解してしまえばとても便利で、すっきりとしたプログラムが書けるようになるんですよ。
今回はそんなJavaの継承について、入門者にもわかりやすいように、やさしく解説をしてみました。是非これを読んでオブジェクト指向プログラミングへの理解を深めてみてくださいね!
継承とは?イメージで解説!
継承とは、Javaをはじめとしたオブジェクト指向プログラミング言語がもつ特徴の一つです。クラスの中身である変数やメソッドを、他のクラスに受け継がせる(=継承する)ことができます。
元となるクラスを親クラス(スーパークラス/基底クラスともいいます)、受け継ぎ先のクラスを子クラス(サブクラス/派生クラスともいいます)と呼びます。
イメージの図で表すと、こんな感じです。
この図では、動物と言う親クラスを継承して、猫・人間という二つのクラスを作っています。猫も人間も同じ動物で、名前と年齢を持つという特徴は共通とします。(名前のない猫もいますがそれは置いておいて)しかし、猫はニャーと鳴きますが人間は言語を話します。また猫はネズミを狩りますが、人間は仕事をします。(仕事をしていない人間も以下略)
共通の項目・性質をもった複数のクラスをつくるというような状況のときに、継承を使うんですね。
継承の書き方とは?
処理
}
publicのところはクラス修飾子です
Aは子クラス、Bは親クラスです。基本の書き方は、子クラス名の後にextendsをつけて親クラスの名前を記します。
動物クラスを継承するために、先ほどの猫と人間の例で、どのような変数とメソッドを作成するかを考えてみましょう。
動物クラスには名前・年齢という変数を持たせました。そして共通のメソッドとして歩く、食べるメソッドを入れましょう。猫クラスには上記に追加してニャーと鳴くメソッド、狩りをするメソッド。人間クラスにはしゃべるメソッド、仕事をするメソッドを加えましょう。
これを基にプログラミングしたクラスはこのようになりました。
//親クラスとなる動物クラス
public class Animal{
public String myname; //名前
public int age;//年齢
public void eat(String something) {
//食べる
System.out.println(something + "を食べました");
}
public void walk(int a){
//歩く
System.out.println(a.toString(); + "メートル歩きました");
}
}
//動物クラスを継承して作った、ねこクラス
public class Cat extends Animal {
//鳴く
public void meow(){
System.out.println("ニャー");
}
//狩りをする
public void hunt() {
}
}
public class Human extends Animal {
//しゃべる
public void talk(String tk){
System.out.println("「" + tk + "」");
}
//仕事をする
public void wokr(){
}
}
継承を使うメリットとは?
継承を使うメリットは大きく分けて二つあります。まず一つはプログラミングする行数が減り、手間も減るということです!
例えば先ほどの動物クラスの例ですと、継承を使わずに書くと猫クラス・人間クラスは以下のようになります。
//動物クラスを継承しないで作った、ねこクラス
public class Cat {
public String myname; //名前
public int age;//年齢
public void eat(String something) {
//食べる
System.out.println(something + "を食べました");
}
public void walk(int a){
//歩く
System.out.println(a.toString(); + "メートル歩きました");
}
//鳴く
public void meow(){
System.out.println("ニャー");
}
//狩りをする
public void hunt() {
}
}
public class Human extends Animal {
public String myname; //名前
public int age;//年齢
public void eat(String something) {
//食べる
System.out.println(something + "を食べました");
}
public void walk(int a){
//歩く
System.out.println(a.toString(); + "メートル歩きました");
}
//しゃべる
public void talk(String tk){
System.out.println("「" + tk + "」");
}
//仕事をする
public void wokr(){
}
}
先ほどの例に比べてプログラミングの行数が大幅に増加してしまいましたね。ふたつのクラスに重複してしまう部分については、変更があった場合に両方のクラスを修正しなくてはならなくなります。継承を使って親クラスに重複部分がまとまっていれば、修正も一箇所で済みますし、わかりやすいですね。
さて、メリットのもう一つは同じ継承元のクラスを、まとめて扱うことができることです。例えば”動物は全てまとめて船に乗せる”といったことをやりたい場合に、同じ動物というクラスを継承していればひとまとめに変数として扱うことができます。例えばこんなふうに。
//動物クラスの型のオブジェクトを格納する配列
Animal[] animals;
//ねこも、人間も、犬もまとめられる
animals = { new Cat(); new Human(); new Dog()};
継承をうまく使えば非常にすっきりとしたプログラミングコードをかけるようになります。オブジェクト指向の醍醐味でもある、スマートなクラス設計を助けてくれるとても強力なツールになりそうですね。
継承の特徴、注意事項とは?
継承を使う際の、特徴と注意事項を見ていきましょう。
子クラスでは親クラスのフィールド(変数、メソッド)を使える
継承の一番の特徴ですね。下の図のように、見えないけれど親の機能を持っていると考えるとわかりやすいかもしれません。
子クラスで親クラスのメソッドの上書きができる
継承したメソッドを、上書き(オーバーライド)することができます。これにより、同じ名称のメソッドでも異なる機能を持たせることができます。引数を揃える必要があることだけ、注意してくださいね。
3.親クラスに final を使ったフィールドは上書き禁止
finalをつけると、オーバーライドができないメソッドになります。勝手に処理を変更されたくない場合につけると良いでしょう。static,privateなどもメソッド・変数の扱いが変わります。詳細はまた別の記事で説明しますので省略しますが、継承クラス内で使う場合は注意しましょう。
二つのクラスを同時に継承することはできない
class A extends B,C などと、複数のクラスを継承することはできません。
継承の継承はできる
子クラスを親とする孫クラスは作成が可能です。
public class Animal {
}
public class Cat extends Animal {
}
pubic class BlackCat extends Cat {
public String color = "black";
}
猫クラスを親とした黒猫クラスを作ってみました。
子クラスのインスタンスを親のオブジェクトのインスタンスとして扱うことができる
前項継承を使うメリット内で述べたように、親のオブジェクトとしてまとめて扱うことができます。ちなみに、すべてのJavaのオブジェクトは、java.lang.Objectクラスの派生クラスなんですよ。だから、Objectでまとめることができるんですね。
コンストラクタは継承されず、暗示的に実行される
継承されたクラスでコンストラクタを記述する際には、注意が必要です。
public Dog extends Animal {
//コンストラクタ
Dog(){
}
}
public Dog extends Animal {
//コンストラクタ
Dog(){
super();
}
}
上と下のサンプルは同じ意味になります。子クラスでコンストラクタを上書きしようとしても、暗示的に、親クラスのコンストラクタも実行されてしまうのです。子クラスにコンストラクタがない場合も、親クラスのコンストラクタは実行されています。
もう一歩上のテクニック
抽象クラスを使う
子クラスを作って、メソッドや変数をオーバーライドして使って欲しい。しかも、ちゃんともれがないようにしたいな。そんなクラス設計を行いたいときに使えるのが、抽象クラス・抽象メソッドという概念です。
メソッドの修飾子にabstractを使うと、継承先のクラスに対象のメソッドがオーバーライドされていない場合にエラーとなります。abstract(=抽象的な)メソッドは中身を空っぽにしておく必要があります。また、abstractメソッドをもつクラスは、abstractクラスにしないといけません。
abstract public class Animal {
//中身のないabstractメソッドを作っておく
public abstract void eat{
}
}
public class Dog extends Animal{
pubic void eat(){
//オーバーライドしないとエラーになります
System.out.println("ドッグフードを食べます");
}
}
メソッドの上書きをしても、親クラスのメソッドを使うことができる
子クラスでオーバーライドしていても、あえて親クラスのメソッドを使いたい・・・そんな時は
super.メソッド名();
で呼び出すことができます。
\エンジニア最強言語のJavaスキルが身に付く/
まとめ
オブジェクト指向プログラミングでの継承は、Java だけでなくPHP、Python、JavaScriptなど様々なプログラミング言語で採用されている考え方です。理解し、身につけておいて損はないですよ。ぜひ活用してクールなコードをたくさん書いてくださいね!
- この記事を書いた人
- のりぴよ