Web Analytics Made Easy - StatCounter

Economics Of TEC

RPA,経済学,IT技術などに関する情報を発信しています。

【C#入門】カプセル化とは?アクセス修飾子の種類と使い方を紹介

f:id:WillSpecter:20200811195608j:plain

C#を勉強していると、「クラス」「メソッド」「インスタンス」など色んな用語が出てきます。

今回は、オブジェクト指向でプログラミングする際に使える、「カプセル化」について事例も含めて紹介します。

メソッドやクラス、インスタンス・コンストラクタについてはこちらの記事を参考にしてください。

 

 

 

 

カプセル化とは

カプセル化とは、メンバ変数やメンバメソッドを他のクラスからアクセスできないようにすることです。

 

メソッドにアクセスするとき、アクセス修飾子をつけますが、それで調整することができます。

 

◆アクセス修飾子の種類◆
public:すべてのクラスからアクセス可能
protected:自分のクラスまたは派生クラスからのみアクセス可能
private:自分のクラス以外からはアクセス不可能

 

前回の例でいうと、Murabito.csの変数にはpublicを設定していました。

    class Murabito
    {
        public string name; //村人の名前 
        public int hp;   //村人の体力

ここをprivateに変更すると、「カプセル化した」ということになります。

 

なぜカプセル化をするのか?理由は2つあります。 

カプセル化の役割◆
1.クラスの中で、利用してほしい機能だけ使えるようにする
2.クラスを使う人がメンバ変数におかしな値をいれないようにする

このように、見る必要のないものは隠し、使わせたいメンバだけにアクセスできるようにするのですね。これもプログラムをより正常に動かすための仕組みです。

アクセス修飾子のつけ方

アクセス修飾子はメンバ変数の宣言やメソッドの定義の手前につけます。

        //アクセス修飾子のつけ方例

        //アクセス修飾子 型名 メンバ変数名;
        public string name;
        private int hp;

        //アクセス修飾子 戻り値の型 メンバメソッド名;
        public void Discuss() { 処理~};
        private void Vote() { 処理~};
仮に、アクセス修飾子を省略した場合は、privateをつけて宣言したものとみなされます。

アクセス修飾子のパターンと結果

では、前回作成したProgram.csとMurabito.csを使ってアクセス修飾子を変更するとどのような結果になるかを見ていきましょう。ソースはこちらの記事にあります。

  

■Murabito.cs内で定義する変数をPrivateにするケース

Mainメソッドから呼び出されるMurabitoクラスで定義した変数をPublicからPrivateに変更しました。

    class Murabito
    {
        private string name; //村人の名前 
        private int hp;   //村人の体力
続いて、呼び出し元のProgram.csのMainメソッドで2つのパターンを書いてみます。
パターン2は直接hpに数値を代入したものです。
        static void Main(string[] args)
        {
            //村人1のインスタンスを作り、名前と体力を代入
            Murabito murabito1 = new Murabito("たかし",200);  //パターン1
            murabito1.hp = 120;                              //パターン2

■結果

パターン1はエラーにならないですが、パターン2では、"アクセスできない保護レベル"

というエラーメッセージが表示されます。

f:id:WillSpecter:20200814113449p:plain

CS0122_アクセスできない保護レベルになっています

以上のように、呼び出し先のMurabito.csで変数をカプセル化(private)した場合、直接値を代入することができません。

一方で、引数で値を渡した場合は、publicなコンストラクタを利用しているので、値を渡すことができます。

メンバ変数にアクセスする方法

先ほどは、どのような値でも、hpの変数を代入できない保護レベルでしたが、正しい値は代入できるようにしたいですね。その場合は、ンバ変数に値を代入・取得するメンバメソッドを追加することで、対応できます。少しレベルアップした内容になりますが、紹介させていただきます。 

■例題

<やりたいこと>

・Murabito1の体力を減らした値を現在のhpとして代入する 

・マイナスの体力は0とする(マイナスの体力は入らないように)

<メンバメソッド>

SetHpでは、渡した値をhpにセットするのですが、もしマイナスであれば0を代入しています。今回はマイナスになったNewHpを渡します。

GetHpではHpを返します。SetHpでhpをマイナスから0にした値をGetHpで返します。

このようなメンバ変数にアクセスするメソッドをアクセサといいます。 

アクセサで値の整合性をチェックすることで、メンバ変数におかしな数値が入ることを防ぎます(今回の例だと、変数hpにマイナスが入らないようにする)。

 

■Progmam.cs

using System;

namespace JinroGame
{
    class Program
    {
        static void Main(string[] args)
        {
            //村人1のインスタンスを作り、名前と体力を代入
            Murabito murabito1 = new Murabito("たかし",200); 
            //現在のhp
            int hp = murabito1.GetHp();

            //体力が減る
            int NewHp = hp - 3000;

            //減った体力をhpに代入する
            murabito1.SetHp(NewHp);

            //現在のhpを表示する
            Console.WriteLine("現在の体力は" + murabito1.GetHp());
        }
    }
}

 

■Murabito.cs

using System;
using System.Collections.Generic;
using System.Text;

namespace JinroGame
{
    class Murabito
    {
        private string name; //村人の名前
        private int hp;   //村人の体力

        //コンストラクタで引数を初期値に代入
        public Murabito (string name,int hp)
        {
            this.name = name;
            this.hp = hp;
        }
        //hpがマイナスの場合は0をセットする
        public void SetHp(int hp)
        {
            this.hp = hp;
            if (this.hp <0)
            {
                this.hp = 0;
            }
        }
        //hp変数の値を取得する
        public int GetHp()
        {
            return this.hp;
        }
    }
}

 

ひとこと

C#を初めて間もないころは、とりあえず他のソースを真似て、publicにしておこう、という方もいるかもしれません。ただ、意味を知ることで、他人のソースを読むときに「なぜPrivateにしたのか??」と意図がつかめるようになり楽しくなります(^^)この点、私には英語の文法を勉強している感覚と似ているな、と感じています。

 

今回の説明は「確かな力が身につくC# 「超」入門」を参考にさせていただきましたが(例題はオリジナルです)、「もっと前から読んでおきたかった!」と痛感しています、、。もし、C#について学び始めたという方は是非参考にしてみてください!(2020年7月に出版された新書です(^^)

 

次回は、先ほどの例題をさらに簡素にまとめるプロパティという仕組みについてご紹介いたします!