継承 -基礎-

ホームC#プログラミング応用講義 > 基礎

目次

継承とは?

「継承」
オブジェクト指向において最も重要な考え方であり、身に付けるとパワフルで、身に付けなければならぬ重要項目です。

しかし、重要なものに限って難しいもので、それはこの継承も例外ではありません。
とはいえ、ゆっくりと理解すれば確実に身に付く項目でもあります。

ということで、たとえ一読してわからなくてもあきらめないでください。わからなくても全然問題ありません。なんたって、オブジェクト指向の3本柱の1つですから、いくら時間をかけてもいいのです。

前置きはこのくらいにして「継承」というその意味を理解してみましょう。実際にコードが登場するのは後ですから、ただ読んでいきましょう。

「継承」 ・・・ うけつぐこと。
広辞苑にはこうありました。まさにそう、受け継ぐことこそが継承なのです。

話を具体的にしていきましょう。
CROWN の継承

CROWN という車があります。高級車の中の高級車ですが、ここではそれは問題ありません。
CROWN でも「トヨタ」の車であることに異存はありません。よって、その上に「トヨタ」とかかれています。

トヨタでもホンダでも乗用車を販売しており、ここでも例外ではなく「CROWN」は乗用車に属しています。
よって、その上に「乗用車」とかかれています。

どんどん範囲が広くなってきます。乗用車はなんといっても「車」であり、トラック・バスなども「車」に属します。そのため「車」と、乗用車の上に書いてあります。

さあ、いよいよ最後です。車は船・飛行機などの「乗り物」に属します。ここでは乗り物以上に広い範囲はなく、「乗り物」が最も大きな分類です。
ここでは CROWN を定義する際に「乗り物」から順に幅を狭めていくと、実際に「CROWN」を定義する際に定義していない部分だけすればいいのです。

乗り物の段階で「移動する」「速度」などを定義し、車の段階で「タイヤで動く」「エンジンつき」を、乗用車の段階で「4つの座席」を、トヨタの段階で「マーク」を定義すると、いざCROWNを定義する際には「排気量」「高級車」などを定義するだけで済みます。
この順番に定義していく方法を使えば、トヨタの 「WISH」 という車を定義する際にトヨタまで定義済みなので簡単になるのです。

車からクラスへ

前回は車について具体的な話をしてきましたがこの項目でクラスへと、プログラミングに転換します。

ある機能を実装したいクラスがあるとします。その際にクラスを「完全に独立した単体」としてだけ考えていると、上のような便利な定義方法に気づきません。
もっと幅の広い部分で別のクラスとして定義しておき、徐々に幅を狭め、最終的なクラスでその機能を完成させればいいのです。

この「段階的定義」とでも言うものは「うけつぐこと」に他なりません。広い範囲から徐々に受け継いで定義していく。それができないといちいちすべてを定義しなければなりません。

このような「うけつぐこと」を広辞苑どおり「継承」と呼びます。

ここで最も重要なことは最終的なクラスはそれまでのすべてのクラスをすべて含んでいるということです。継承の手続きをすれば、すべてをうけつぐことができます。
継承の手続きは非常に簡単なものです。クラスを定義する際に一言書けばいいだけです。
class 狭いクラス : 広いクラス
{
    :
    :
}
「狭いクラス」とはこれまで通り普通の「クラス」を書けばよく、その後ろに「: コロン」を記述し、受け継ぐ基となるクラスをその後に書けば終わりです。
これだけで、「広いクラス」に定義されたすべてのメンバは「狭いクラス」に受け継がれます。

何を「広いクラス」に、何を「狭いクラス」に定義するかはプログラマの力量です。より一般的なものを広いクラスに、より具体的なものを狭いクラスに定義しなければなりません。
次の項目では一般的なものと具体的なものの区別に「ドラマ」を選んでみました。というのは建て前で、単なる私の趣味です。

ついつい言うのを忘れたのですが、「広いクラス」のことを「基本クラス」、「狭いクラス」のことを「派生クラス」と呼びます。これらは別称として「スーパークラス」「サブクラス」という呼び方もされますが、日本語名のほうが的確に伝えられるでしょう。
一般的な会話では「狭いクラス」などとは言わないので、これらの用語は覚えておくべきでしょう。

ドラマとトリックの関係

変な項目名だからといって読み飛ばさないように。実際に継承を使う重要な項目です。

using System;

class DoramaBase
{
    // (1) 基本クラスのメンバ
    public string title;
    public string actor;
    public void CM()
    {
        Console.WriteLine("ドラマ名:" + title);
        Console.WriteLine("主演:" + actor);
    }
}

class TRICK : DoramaBase
{
    // (2) 自分のクラスのメンバ
    string myReview;
    
    // (3) Main() メソッド
    public static void Main(string[] args)
    {
        // (4) 自分のクラスのオブジェクトを生成
        TRICK trick = new TRICK();
        // (5) 基本クラスにもアクセスできる
        trick.title = "TRICK";
        trick.actor = "仲間由紀恵";
        // (6) 自分のクラスは当然できる
        trick.myReview = "ちなみに、最も好きなドラマです。";
        
        // (7) これも自分のクラスのメンバ
        trick.ShowReview();
    }
    
    // (8) 自分のクラスのメンバ
    private void ShowReview()
    {
        CM();
        Console.WriteLine(myReview);
    }
}
まず、このプログラムの中にクラスがいくつあるか確認してください。

誰でもわかりますが、2つです。「DoramaBase」クラスと「TRICK」クラスです。
しかし、これらは並立関係にはありません。

TRICK クラスの定義部分を見てください。
class TRICK : DoramaBase
先ほど説明した「コロン」があります。DoramaBase を基本クラスとした TRICK クラスを定義していることが伺えます。

コメントに順番を打っていますから、その順に見ていきましょう。順番といってもただ上からつけただけです。

(1)
DoramaBase クラスに定義された変数とメソッド、あわせて3つのメンバです。別に変わったことはありません。

(2)
2, 3, 8 はすべて TRICK クラスに宣言された変数とメンバ、合わせて3つです。
特に (2) は TRICK 固有のレビューを入れたいので、普通のドラマ用のクラスには定義されていない変数を定義しました。

(3)
ただの Main() メソッドです。

(4)
これまで自分自身のクラスをオブジェクトとして生成することはしてきませんでしたが、普通にできます。改めて言いますが、これは TRICK クラスのオブジェクトです。
なぜそうしたのかというと、メンバが static で宣言されていないからです。これは復習になりますね。

(5)
4 において trick が TRICK クラスのオブジェクト(参照)であると書いたのですが、TRICK は DoramaBase から派生されているため、基本クラスのメンバにもアクセスできます。
まるで自分のクラスの中にあるかのように使えるところが不思議ですが、すべて取り込んだと考えればいいでしょう。

(6)
コメントどおりです。アクセスしているのは自分自身の変数です。

(7)
コメントどおりです。アクセスしているのは自分自身のメソッドです。

(8)
7 で呼び出したメソッドです。この中で
CM();
とあるのが DoramaBase から受け継いだメソッドです。自分の中に取り込んでいるので、TRICK にあるかのようにアクセスできます。

DoramaBase はすべてのドラマに使います。しかし、TRICK はトリックだけで、具体的な内容が含まれます。
YamatoNadeshiko クラスを作れば「やまとなでしこ」用のクラスができますし、Gokusen クラスを作れば「ごくせん」用のクラスができます。

これらはすべて TRICK と同じ具体的な内容が含まれ、DoramaBase を継承することで一般的な内容である「ドラマ名」と「主演」を継承できます。
継承を利用すれば非常にスマートにプログラミングができます。

もちろん、混乱してはいけません。上のプログラミングでは「myReview」は基本クラスではなく派生クラスに定義していることからして、別のドラマにはレビューをつけないことがあるということです。
この場合はレビューをつけないものが多いという可能性のほうが多いでしょう。

基本クラスのメンバかどうか、それに混乱してはいけません。
次回は継承について深く理解していきましょう。

[ ステップアップC# ] [ C#プログラミング応用講義 ]