C#初心者によるC#のお勉強やろう13 継承編

日が暮れるのも早くなりましたね。el(える)です。

 

今回は継承編です。

さっぱり分からないのでいざお勉強です。

継承編

プログラムを作っていくと、類似したクラスを作ることがあります。

たとえば、Playerクラスと敵クラスはどちらもHP変数や攻撃メソッドを持つという点では似ていました。

 似たようなメンバを持つクラスを何度もプログラミングするのは冗長に感じます。 

 

継承は クラス同士で重複している部分だけのクラスを作り、重複をなくす仕組みです。 

たとえば、クラスAとクラスBで重複している部分を取り出してクラスCを作っておき、

クラスA とBを作るときはクラスCを利用するという具合に継承を使います。

01レースゲームに必要なクラスを考える

今回作るゲームには、飛行カートとターボカートの2種類を登場させます。

1.アプリケーション内で変化する可能性のあるものを書きだす。

今回作るゲームで動くものは飛行カートとターボカートです。

2.書き出したものそれぞれに属する値を列挙する

カートに属する値としては重量や速度、ガソリンの量などが考えられます。

レースゲーム用のカートに使えそうな値をメンバ変数にします。

3.書き出したものそれぞれに対応する動作や処理を列挙する

アクセルを踏む動作は両方のカートに必要ですね。

飛行カートには飛ぶための離陸機能、ターボカートにはターボ機能を追加します。

 

クラスを書き出せたので実際にプログラムを作っていきましょう。

02継承をつかわずにSkyKartクラスを作ってみる

これまで同様に新規作成にてプロジェクト名KartGameを作ります。

その後、これまでと同じように、クラスを作ります。

クラス名はSkyKart.csとします。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace KartGame
{
    class SkyKart
    {
        public int weight;
        public int speed;

        public void Force()
        {
            Console.WriteLine("加速");
        }

        public void Flying()
        {
            Console.WriteLine("離陸");
        }
    }
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace KartGame
{
    class Program
    {
        static void Main(string[] args)
        {
            SkyKart skyKart = new SkyKart();
            skyKart.Force();
            skyKart.Flying();
        }
    }
}

SkyKartクラスでは、カートの重量(weight)と速度(speed) を表すメンバ変数と、

加速(Force)と離陸(Flying)するメンバメソッドを作成しています。

Mainメソッドの中ではSkyKartクラスのインスタンスを作り、

ForceメソッドとFlyingメソッドを順番に呼び出しています。

今回は簡略化してメッセージを表示するのみとしています。

03継承を使わずにTurboKartクラスを作ってみる

前と同様にクラスを作ります。名前はTurboKart.csとします。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace KartGame
{
    class TurboKart
    {
        public int weight;
        public int speed;

        public void Force()
        {
            Console.WriteLine("加速");
        }

        public void Turbo()
        {
            Console.WriteLine("ブースト");
        }
    }
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace KartGame
{
    class Program
    {
        static void Main(string[] args)
        {
            TurboKart turboKart = new TurboKart();
            turboKart.Force();
            turboKart.Turbo();
        }
    }
}

TurboKart.cs

04継承を使わずに作った場合の問題点

順調にカートを作っていたのですが、 ゲームを作っているうちにForceメソッドは加速だけでなく、減速もできる方がよいことがわかりました。   SkyKart.csとTurboKart.csのForceメソッドを修正する ことになります。

今回は用意したカートが2種類だけなので、2ヶ所の修正だけでした。

しかし、カートのクラスが40種類あった場合、すべてのForceメソッドを修正することになり、とても大変です。

クラス間で重複している個所に修正が必要になった場合、

 重複しているクラスの数に比例して修正する箇所が増えていく ことになります。

05継承を使ってカートを作り直そう

継承を使うことで問題を解決できます。

まずは新しくKartクラスを追加しましょう。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace KartGame
{
    class Kart
    {
        public int weight;
        public int speed;

        public void Force()
        {
            Console.WriteLine("加速");
        }
    }
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace KartGame
{
    class SkyKart: Kart
    {

        public void Flying()
        {
            Console.WriteLine("離陸");
        }
    }
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace KartGame
{
    class TurboKart: Kart
    {

        public void Turbo()
        {
            Console.WriteLine("ブースト");
        }
    }
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace KartGame
{
    class Program
    {
        static void Main(string[] args)
        {
            SkyKart skyKart = new SkyKart();
            TurboKart turboKart = new TurboKart();

            skyKart.Force();
            skyKart.Flying();
            turboKart.Force();
            turboKart.Turbo();
        }
    }
}

継承

継承は クラス間で重複している部分を取り出して新しくクラスを作り、プログラムの重複をなくす仕組み です。

Kartクラスを元にSkyKartクラスとTurboKartクラスを作っています。

既存のクラスの機能を引き継いで新しいクラスを作ることを継承と呼び、

継承元のクラスを基本クラス、継承したクラスを派生クラスいいます。

今回の例では、Kartクラスが基本クラス、SkyKart、TurboKartクラスが派生クラスになります。

派生クラスは基本クラスが持っているメンバ変数やメンバメソッドを引き継ぎします。

class SkyKartに続けて: Kartと書くことでSkyKartがKartクラスを継承しています。

継承を使ったクラスの書式

class 派生クラス名 : 基本クラス名

06継承を使ったクラスに減速機能を追加してみよう

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace KartGame
{
    class Kart
    {
        public int weight;
        public int speed;

        public void Force()
        {
            Console.WriteLine("加速&減速");
        }
    }
}

 

Kartクラスに一行書き出しただけです。

 Kartクラスを修正するだけでSkyKartとTurboKartクラスにも修正が反映されます。 

 

継承は何段階でもできる

今回はKartクラスを継承してSkyKartクラスとTurboKartクラスを作りました。

TurboKartクラスをさらに継承して、ターボ機能を強化したSuperTurboKartクラスのような派生クラスを作ることもできます。

 クラスは何段階でも継承できます。 

 

継承とアクセス修飾子

アクセス修飾子の時にprotectedというキーワードがありました。

protectedを含めた3つのアクセス修正しについて説明します。

基本クラスのアクセス修飾子 基本クラス自身のアクセス 派生クラスからのアクセス 外部クラスからのアクセス
public
protected ×
private × ×

基本クラスでpublicと宣言したメンバは、派生クラス、外部クラスからも使用できます。

publicはオープンな修飾子です。

privateをつけて宣言したメンバは派生クラスからも外部クラスからもアクセスできません。

privateは自分だけの秘密な修飾子です。

protectedは派生クラスからはアクセスできるけれど、外部クラスからはアクセスできない身内にはオープン、他人には秘密な修飾子です。

終わりに

今回の継承は分かりやすかったですね。

なかなか便利なものです。

まぁ覚えておかないと意味がないのですけど。。。

他のC#の本もまた読むつもりなので、そのうち覚えるでしょう。

 

多分おすすめのC#の本です。

前回おすすめしている本には分かりやすさで劣るんですが、

一応、amazonでも評価が高そうな本です。

読まないよりは読んだ方が知識が身につくと思います。

僕はなぜこんなに本を持っているのでしょう。。。

阿呆なんでしょうね・・・

 

 

それではまた次回。

 

 

 

刀剣好きのメルマガ




 

シェアしてくれたら嬉しいです!!

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です