Java入門 STEP12|継承を学ぼう

karin@taishi@felmia

ここまで、クラスやコンストラクタ、カプセル化について学んできました。

このSTEPでは、オブジェクト指向の重要な仕組みのひとつである「継承」について学びます。

継承を使うと、すでに作成したクラスの機能を別のクラスに引き継ぐことができます。

まずは、継承がどのような仕組みなのか、簡単な例から確認します。

継承とは?

例えば、動物を表すAnimalクラスを作ったとします。

public class Animal {

    public void eat() {
        System.out.println("食べます");
    }
}

このクラスには、食べることを表すeat()メソッドがあります。

次に、犬を表すDogクラスを作るとします。

犬も動物なので、Animalクラスと同じeat()メソッドを持たせたいところです。

もちろん、Dogクラスにも同じメソッドを書くことはできます。

public class Dog {

    public void eat() {
        System.out.println("食べます");
    }
}

しかし、同じようなクラスが増えるたびに共通する処理を書くのは大変です。

そこで利用できるのが継承です。

継承とは?

すでに作成したクラスのフィールドやメソッドなどを、別のクラスに引き継ぐ仕組みです。

共通する機能をまとめることで、同じようなコードを何度も書くことを減らせます。

継承される側のクラスを親クラス(スーパークラス)、継承する側のクラスを子クラス(サブクラス)と呼びます。

今回の場合は、

Animal → 親クラス
Dog → 子クラス

となります。

extendsを使って継承しよう

Javaでクラスを継承するときは、extendsを使います。

基本的な書き方は次のとおりです。

class 子クラス名 extends 親クラス名 {

}

extendsの後ろに、継承したい親クラスを指定します。

先ほどのAnimalクラスをDogクラスで継承すると、次のようになります。

public class Dog extends Animal {

}

これで、DogクラスはAnimalクラスを継承したことになります。

つまり、

Dog extends Animal

は、

「DogはAnimalを継承する」

という意味になります。

extendsの書き方

class 子クラス名 extends 親クラス名 {

}

extendsの左側が子クラス、右側が親クラスです。

継承したメソッドを使ってみよう

次は、継承したメソッドを実際に使ってみます。

まず、親クラスとなるAnimalを作成します。

public class Animal {

    public void eat() {
        System.out.println("食べます");
    }
}

続いて、Animalを継承するDogクラスを作成します。

public class Dog extends Animal {

}

Dogクラスの中には、まだ何も書いていません。

最後に、MainクラスでDogのオブジェクトを作成し、eat()を呼び出します。

public class Main {

    public static void main(String[] args) {

        Dog dog = new Dog();

        dog.eat();
    }
}

実行結果

食べます

Dogクラスにはeat()メソッドを書いていません。

それでも、

dog.eat();

と書いて、eat()メソッドを呼び出すことができました。

これは、DogがAnimalを継承しているためです。

Animalが持っているeat()メソッドを、子クラスであるDogでも利用できます。

ルミィ
ルミィ

Dogにはeat()を書いてないのに使えた!
これが親クラスの機能を引き継ぐってことなんだね♪

子クラス独自のメソッドも作れる

子クラスでは、親クラスから引き継いだ機能だけしか使えないわけではありません。

子クラス独自のフィールドやメソッドを追加することもできます。

先ほどのDogクラスに、犬が鳴く動作を表すbark()メソッドを追加します。

public class Dog extends Animal {

    public void bark() {
        System.out.println("ワン!");
    }
}

Dogには、

親クラスから引き継いだeat()

と、

Dog自身が持っているbark()

の2つのメソッドがあります。

eat()とbark()をそれぞれ呼び出します。

public class Main {

    public static void main(String[] args) {

        Dog dog = new Dog();

        dog.eat();
        dog.bark();
    }
}

実行結果

食べます
ワン!

eat()はAnimalから引き継いだメソッドです。

一方、bark()はDog自身に作成したメソッドです。

このように子クラスでは、

親クラスから引き継いだ機能 + 子クラス独自の機能

を持たせることができます。

親クラスと子クラスの関係

継承では、親クラスと子クラスの関係も重要です。

今回作成したクラスは、

Animal → 動物
Dog → 犬

を表しています。

犬は動物の一種なので、

「DogはAnimalの一種である」

という関係が成り立ちます。

このような関係は、英語で

Dog is an Animal.

と表すことができます。

継承では、この「is-a」の関係がひとつの考え方になります。

継承を考えるときのポイント

単に「同じ処理があるから」という理由だけで、すべて継承すればよいわけではありません。

「子クラスは親クラスの一種と言えるか?」

という関係も考えてみましょう。

ルミィ
ルミィ

「同じ処理があるから継承!」だけじゃないんだね。
「○○は△△の一種」って考えると分かりやすそう♪

Javaでは複数のクラスを継承できない

Javaの継承には、もうひとつ覚えておきたいルールがあります。

Javaでは、1つのクラスが複数のクラスを同時に継承することはできません。

例えば、次のような書き方はできません。

public class Dog extends Animal, Pet {

}

extendsで指定できる親クラスは1つだけです。

Javaのクラス継承

Javaでは、

1つの子クラスがextendsで継承できる親クラスは1つです。

複数のクラスを同時にextendsすることはできません。

複数の性質を持たせたい場合には、後ほど学習するインターフェースなどを利用できます。

今の段階では、extendsで指定できる親クラスは1つと覚えておけば大丈夫です。

privateなフィールドには直接アクセスできない

STEP11では、privateを使ってフィールドへの直接アクセスを制限する方法を学びました。

継承した場合でも、このprivateには注意が必要です。

例えば、Animalに次のフィールドがあるとします。

public class Animal {

    private String name;
}

DogはAnimalを継承しています。

しかし、子クラスだからといって次のようにnameへ直接アクセスすることはできません。

public class Dog extends Animal {

    public void showName() {
        System.out.println(name);
    }
}

nameにはprivateが指定されているため、Dogから直接アクセスするとエラーになります。

privateは子クラスからも直接アクセスできない

親クラスを継承していても、親クラスのprivateなフィールドへ子クラスから直接アクセスすることはできません。

必要な場合は、STEP11で学習したgetterなどを利用します。

よくある間違い

extendsの順番を逆にしてしまう

extendsを書くときは、

class 子クラス extends 親クラス

となります。

今回の場合は、

public class Dog extends Animal

です。

DogがAnimalを継承するため、Dog extends Animalの順番になります。

継承すれば何でも直接使えると思ってしまう

継承すると親クラスの機能を利用できますが、すべてを自由に操作できるわけではありません。

特に、親クラスでprivateが指定されているフィールドなどには、子クラスから直接アクセスできません。

アクセス修飾子について分からなくなった場合は、STEP11のカプセル化も確認してみましょう。

STEP12のまとめ

今回は、Javaの継承について学びました。

STEP12のポイント

  • 継承は、すでに作成したクラスの機能を別のクラスへ引き継ぐ仕組み
  • 継承にはextendsを使う
  • 継承される側を親クラス(スーパークラス)という
  • 継承する側を子クラス(サブクラス)という
  • 子クラスでは親クラスから引き継いだメソッドを利用できる
  • 子クラス独自のフィールドやメソッドも追加できる
  • extendsで継承できる親クラスは1つ
  • 親クラスのprivateなフィールドには子クラスから直接アクセスできない

最初は、「親クラスが持っている機能を子クラスでも使える」というところを理解できれば大丈夫です。

ルミィ
ルミィ

STEP12クリア!
親クラスの機能を子クラスに引き継げるのが継承なんだね♪

次のSTEPへ

次のSTEPでは、親クラスから受け継いだメソッドの処理を変更できる「オーバーライド」について学びます。

STEP12では、継承を使うことで親クラスの機能を子クラスでも使えることを学びました。

しかし、子クラスによっては、親クラスと同じ処理ではなくそのクラスに合った処理に変えたいことがあります。

例えば、動物が鳴く処理を考えた場合、

Dogなら「ワン!」

Catなら「ニャー!」

のように、それぞれ違う処理にしたい場合があります。

オーバーライドを使うと、親クラスから受け継いだメソッドを子クラス側で書き換えることができます。

→ STEP13「オーバーライドを学ぼう」

学習内容を確認したいときは、Java入門の一覧から各STEPを確認できます。

→ Java入門|初心者が基礎から学べるJava学習ガイド

記事URLをコピーしました