search
テクノロジー

クラスの継承

handa's icon'
  • handa
  • 2023/01/17 06:17
Content image
タイトル

まえがき

仕事でプログラミング研修の講師をやることになりました。私はシステム開発を中心に行っていますが、講師も業務の一つとしています。過去には、HTML/CSS、JavaScript、Python、C#を担当しました。今度もC#です。

講師の実力をはかりたいと、依頼側から「クラスの継承」について動画で説明せよとの依頼がありました。動画はZoomで作るつもりですが、そのための原稿をここに記載します。

 

クラスとは

クラスは2つの背景から生まれました。1つはグローバル変数の反省から、もう1つはプログラムの再利用のしやすさの考慮からです。

 

グローバル変数の反省

グローバル変数とは、プログラムのどこからでもアクセスできる変数です。C#の前身の前身のC言語では、モジュールAにaというグローバル変数を作ると、モジュールB・C・Dからでもアクセスできます。

Content image
グローバル変数にはどこからでもアクセスできる

これは便利な反面、予期しない副作用を生むことにもなります。グローバル変数を使っている場所がわかりづらいので、システムの保守が難しくなります。グローバル変数aに新たな値を持たせる場合は、影響度調査をしなければなりません。これを反省とし、変数にアクセスできるメソッドを制限させる方法として、クラスが考え出されました。

Content image
メンバメソッドでメンバ変数にアクセスする

 

プログラムの再利用のしやすさ

システムの開発効率を高めるには、プログラムを資産として蓄える必要があります。毎回何もかもを最初から開発していては時間がかかりすぎるため、既にあるものはそのまま使おうという発想です。ある分野の処理を行うプログラムをクラスにしておくと、あとで再利用することができます。例えば、システム的なものとしてはファイル読み書きに関するクラス、画面表示に関するクラス、数値計算に関するクラスなど。業務的なものとしては受注クラス、出荷クラス、売上クラスなどです。

Content image
プログラムの再利用の例

 

再利用できるクラスを作るには、それなりのプログラミングのスキルが必要になります。変数名・メソッド名の統一性も必要になります。C#には最初から最低限のクラスが用意されています。また、VisualStudioでC#の開発をする場合、マイクロソフトがクラスのまとまりであるクラスライブラリを提供してくれています。

 

クラスの継承

既にあるクラスを再利用して新たな機能を付け加えたり違う動作をさせたい場合、次の2つの方法があります。

1. クラスを修正する

2. クラスを継承する

 

クラスを修正する

自分(自社、自部門)が持っているクラスであれば、クラスを修正することが可能です。しかし、開発効率向上のためにソフトウェアの再利用を推進している組織では、自分の想いだけでクラスを修正することはできません。ソフトウェアは資産ですので、既にテストが済んでいるソフトウェア資産を修正することは、バグを混入させる可能性があるため、上位レベル(上司、開発プロジェクト、品質管理部門など)の承認が要ります。そのため、重要な・役に立つ機能追加・修正でないと、承認されにくいです。

もちろん趣味のプログラミングや自分以外に関わる人がいないプログラムであれば、自由にクラスを作り変えてかまいません。

 

クラスを継承する

大元のクラスを修正せずに機能を追加したり修正したい場合は、大元のクラスの特徴を引き継いで新しい別のクラスを作ります。このことをクラスを継承するといいます。クラスを継承するなら、ソフトウェアの再利用を推進している組織でも上位レベルの承認が要りません。

大元のクラスを基底クラスといいます。参考書によっては基本クラス、親クラス、スーパークラスと呼んだりもしますが全部同じ意味です。継承して作る新しいクラスを派生クラスといいます。子クラス、サブクラスと呼ぶこともあります。

Content image
基底クラスと派生クラス

 

C#の例

C#でクラスを作り、継承する例を以下に示します。まず、大元のクラスです。上の図の例のように、円クラスとします。

円クラス

円クラスは、円の面積の計算、円周の計算ができます。円の半径を入力すると円の面積を計算するメソッド、円の半径を入力すると円周を計算するメソッドがあります。変数としては半径、直径、面積、円周、円周率があります。

using System;

namespace Enkanren
{
   class En
   {
       public double hankei;
       public double chokkei;
       public double menseki;
       public double enshu;
       public const double pi = 3.14;

       // 円の面積を計算する。
       // 円の面積=半径×半径×円周率
       public void calc_menseki()
       {
           Console.Write("\r\n円の半径を入力してください: ");
           hankei = double.Parse(Console.ReadLine());
           menseki = hankei * hankei * pi;
           Console.Write("半径が{0}の円の面積は{1}です。\r\n", hankei, menseki);
       }

       // 円周を計算する。
       // 円周=直径×円周率
       public void calc_enshu()
       {
           Console.Write("\r\n円の半径を入力してください: ");
           hankei = double.Parse(Console.ReadLine());
           chokkei = hankei * 2;
           enshu = chokkei * pi;
           Console.Write("半径が{0}(直径が{1})の円周は{2}です。\r\n", hankei, chokkei, enshu);
       }
   }

   class Enkanren
   {
       static void Main(string[] args)
       {
           En e = new En();

           e.calc_enshu();
           e.calc_menseki();
       }
   }
}

 

円柱クラス

円クラスを使っているうちに、「円柱の体積も計算したいな」という要望が出たとします。上位レベルに円クラスへの機能追加を相談しましたが、「円柱の体積は円クラスに追加するのではなく、円クラスを継承して円柱クラスを作ってください。」と言われました。そのようにして円柱クラスを作ります。

   class Enchu : En
   {
       public double taiseki;
       public double takasa;

       // 円柱の体積を計算する。
       // 円柱の体積=円の半径×半径×円周率×高さ
       public void calc_taiseki()
       {
           Console.Write("\r\n円柱の円の半径を入力してください: ");
           hankei = double.Parse(Console.ReadLine());
           Console.Write("円柱の高さを入力してください: ");
           takasa = double.Parse(Console.ReadLine());
           taiseki = hankei * hankei * pi * takasa;
           Console.Write("半径が{0}、高さ{1}の円の体積は{2}です。\r\n", hankei, takasa, taiseki);
       }
   }

 

class Enchu : En

この部分が継承を指示しているところです。

 

円柱を計算するメソッド、変数としては体積、高さを追加しました。円柱の体積の計算方法は

円柱の体積=円の半径×半径×円周率×高さ

で、半径と円周率は基底クラスである円クラスに既にあるので円柱クラスには不要です。

 

最終的なプログラム

最終的に、プログラム全体はこのようになります。

using System;

namespace Enkanren
{
   // 基底クラス
   class En
   {
       public double hankei;
       public double chokkei;
       public double menseki;
       public double enshu;
       public const double pi = 3.14;

       // 円の面積を計算する。
       // 円の面積=半径×半径×円周率
       public void calc_menseki()
       {
           Console.Write("\r\n円の半径を入力してください: ");
           hankei = double.Parse(Console.ReadLine());
           menseki = hankei * hankei * pi;
           Console.Write("半径が{0}の円の面積は{1}です。\r\n", hankei, menseki);
       }

       // 円周を計算する。
       // 円周=直径×円周率
       public void calc_enshu()
       {
           Console.Write("\r\n円の半径を入力してください: ");
           hankei = double.Parse(Console.ReadLine());
           chokkei = hankei * 2;
           enshu = chokkei * pi;
           Console.Write("半径が{0}(直径が{1})の円周は{2}です。\r\n", hankei, chokkei, enshu);
       }
   }

   // 派生クラス
   class Enchu : En
   {
       public double taiseki;
       public double takasa;

       // 円柱の体積を計算する。
       // 円柱の体積=円の半径×半径×円周率×高さ
       public void calc_taiseki()
       {
           Console.Write("\r\n円柱の円の半径を入力してください: ");
           hankei = double.Parse(Console.ReadLine());
           Console.Write("円柱の高さを入力してください: ");
           takasa = double.Parse(Console.ReadLine());
           taiseki = hankei * hankei * pi * takasa;
           Console.Write("半径が{0}、高さ{1}の円の体積は{2}です。\r\n", hankei, takasa, taiseki);
       }
   }

   class Enkanren
   {
       static void Main(string[] args)
       {
           // En e = new En();     // 継承する前なら、このようにインスタンスを作る。
           Enchu c = new Enchu();

           // e.calc_enshu();      // 継承する前なら、このようにメンバ関数を呼び出す。
           // e.calc_menseki();    // 継承する前なら、このようにメンバ関数を呼び出す。
           c.calc_enshu();
           c.calc_menseki();
           c.calc_taiseki();
       }
   }
}

 

円柱クラスは、円クラスの特徴を引き継いでいます。円柱クラスのインスタンスを作り、円クラスに定義しているメソッドを呼ぶこともできます。

実行結果を以下に示します。

Content image
実行結果

 

これがクラスの継承の基本です。

 

以上

Supporter profile iconSupporter profile iconSupporter profile icon
Article tip 3人がサポートしています
獲得ALIS: Article like 76.55 ALIS Article tip 15.24 ALIS
Article registration Article registration
handa's icon'
  • handa
  • @handa
コンピュータシステムの開発、子供向けプログラミング教室などを行っています。

投稿者の人気記事
コメントする
Loading...
コメントする
こちらもおすすめ!
Eye catch
クリプト

Bitcoinの価値の源泉は、PoWによる電気代ではなくて"競争原理"だった。

CryptoChick 2020/03/07
Like token Tip token
159.32 ALIS
Eye catch
クリプト

ジョークコインとして出発したDogecoin(ドージコイン)の誕生から現在まで。注目される非証券性🐶

昆布森ちゃん 2021/01/19
Like token Tip token
38.31 ALIS
Eye catch
他カテゴリ

機械学習を体験してみよう!(難易度低)

nonstop-iida 2020/03/04
Like token Tip token
124.82 ALIS
Eye catch
テクノロジー

オープンソースプロジェクトに参加して自己肯定感を高める

おはぐろ氏 2020/02/15
Like token Tip token
85.05 ALIS
Eye catch
テクノロジー

iOS15 配信開始!!

IMAKARA 2021/09/23
Like token Tip token
7.20 ALIS
Eye catch
テクノロジー

彼女でも分かるように解説:ディープフェイク

Jimmy 2020/03/17
Like token Tip token
32.10 ALIS
Eye catch
ゲーム

ドラクエで学ぶオーバフロー

keiju togashi 2020/03/12
Like token Tip token
30.10 ALIS
Eye catch
クリプト

NFT解体新書・デジタルデータをNFTで販売するときのすべて【実証実験・共有レポート】

otakucoin 2021/03/29
Like token Tip token
121.79 ALIS
Eye catch
テクノロジー

なぜ、素人エンジニアの私が60日間でブロックチェーンゲームを制作できたのか、について語ってみた

ゆうき 2020/08/12
Like token Tip token
270.93 ALIS
Eye catch
クリプト

17万円のPCでTwitterやってるのはもったいないのでETHマイニングを始めた話

nnppnpp(んぺー) 2021/09/08
Like token Tip token
46.60 ALIS
Eye catch
クリプト

約2年間ブロックチェ-ンゲームをして

kaya 2021/10/06
Like token Tip token
61.20 ALIS
Eye catch
クリプト

Bitcoin史 〜0.00076ドルから6万ドルへの歩み〜

大田コウキ 2021/04/06
Like token Tip token
947.13 ALIS