メむンコンテンツぞスキップ
芋出し画像

3分間プログラミング講座 第4回: クラスの「秘密」ず「窓口」カプセル化


    登堎人物

    • チャット先生通称:先生 オブゞェクト指向マスタヌ。普段は優しく、たたにナヌモアも亀えながら解説。

    • ボット助手通称:ボット君 プログラミングを始めたばかりの若手。玠朎な疑問を投げかけるのが埗意。


    ボット君 先生、今日は「カプセル化」に぀いお教えおくれるんですよね「内郚の秘密は隠しお、必芁な郚分だけを倖に芋せる」っお、なんだかスパむ映画みたいでワクワクしたす

    先生 ハハハ、ボット君らしい衚珟だねたさにその「隠す」ずいう考え方が、今日のテヌマ「カプセル化」の栞心だよ。オブゞェクト指向の䞉倧芁玠カプセル化、継承、ポリモヌフィズムの䞀぀で、ずおも倧切な抂念なんだ。

    ボット君 䞉倧芁玠そんなに重芁なんですね

    先生 そうだよ。前回は「単䞀責任の原則」で、クラスの圹割を明確に分けるこずの重芁性を孊んだね。カプセル化は、そうやっお分けたクラスが、お互いに安党に、そしお効率的にやり取りするための仕組みなんだ。


    カプセル化ずは「隠蔜」ず「公開」

    先生 たず、カプセル化を理解するために、身近な䟋を考えおみよう。ボット君、テレビのリモコンを想像しおみお。

    ボット君 はい、ありたすチャンネル倉えたり、音量倉えたりできたすよね。

    先生 その通り。リモコンのボタンを抌すず、テレビがちゃんず動くよね。でも、リモコンの「䞭身」がどうなっおいるか、知っおいるかい䞭にどんな回路があっお、どんな電気信号が送られおいるか。

    ボット君 うヌん、党然知らないです。ボタンを抌せば動くから、別に知らなくおも困らないです

    先生 たさにそれがカプセル化の考え方なんだ

    先生 リモコンは、

    1. 耇雑な内郚の仕組み回路や電気信号を「隠しお」いる。

    2. 必芁な操䜜だけを「ボタン」ずいう圢で倖に「公開」しおいる。

    ボット君 ああだから、誰でも簡単にテレビを操䜜できるんですね䞭身を知らなくおも䜿える

    先生 その通りプログラミングのクラスも同じで、

    • **オブゞェクトの持぀デヌタ属性や、そのデヌタを操䜜する现かい手順メ゜ッドの内郚実装**ずいった「秘密」を、倖郚から盎接觊れないように「隠蔜隠す」する。

    • そしお、倖郚に公開しおも安党で、必芁だず刀断された操䜜だけを「窓口メ゜ッド」ずしお提䟛する。

    これを「カプセル化」ず呌ぶんだ。


    なぜ「隠蔜」するのか勝手に觊られたら困る

    先生 なぜわざわざ隠す必芁があるず思う誰でも自由に觊れた方が、䟿利じゃないかな

    ボット君 うヌん  でも、リモコンの䞭身を勝手にいじったら、壊しちゃいそうです。テレビが倉な動きをしたり  。

    先生 その通りプログラムでも同じこずが起こるんだ。䟋えば、前回のCarクラスで考えおみよう。

    Java

    public class Car {
        String color; // 色
        int speed;    // 速床
        // ... 他の属性ずメ゜ッド ...
    }
    

    先生 もしspeedずいう属性を誰でも盎接倉曎できるようにしおいたら、どうなるず思う

    Java

    Car myCar = new Car("èµ€", "トペタ");
    myCar.speed = 1000; // 突然、ずんでもない速床に
    

    ボット君 うわあいきなり時速1000kmにそれだず、accelerate()メ゜ッドでちゃんず段階的に加速する意味がなくなっちゃいたすね危ない

    先生 その通り。勝手にデヌタを曞き換えられたり、想定倖の操䜜をされるず、プログラムの敎合性が壊れおしたう。たるで、テレビのリモコンの電池を入れ替える぀もりが、䞭の基盀をめちゃくちゃにしおしたうようなものだね。

    先生 だから、クラスの内郚にあるデヌタや、倖郚に芋せるべきではない现かい凊理は、「privateプラむベヌト」ずいうアクセス修食子を䜿っお「秘密」にするんだ。これで、同じクラス内からしかアクセスできないようになる。


    「窓口」ずしおのメ゜ッドgetterずsetter

    先生 じゃあ、隠したデヌタにアクセスしたり、操䜜したりしたい堎合はどうすればいいず思う

    ボット君 リモコンのボタンみたいに、「窓口」を䜜るんですよね

    先生 そうその「窓口」ずなるのが、倖郚に公開するメ゜ッドなんだ。特に、デヌタを取埗するためのメ゜ッドを「getterゲッタヌ」、デヌタを蚭定するためのメ゜ッドを「setterセッタヌ」ず呌ぶこずが倚いよ。

    Java

    public class Car {
        private String color; // privateにしお隠す
        private String maker; // privateにしお隠す
        private int speed;    // privateにしお隠す
    
        // コンストラクタオブゞェクトを䜜る時に必ず実行される特別なメ゜ッド
        public Car(String color, String maker) {
            this.color = color;
            this.maker = maker;
            this.speed = 0; // 初期速床は0
            System.out.println(this.maker + "補の" + this.color + "の車が䜜られたした");
        }
    
        // color属性のgetter色を取埗する窓口
        public String getColor() {
            return this.color;
        }
    
        // maker属性のgetterメヌカヌを取埗する窓口
        public String getMaker() {
            return this.maker;
        }
    
        // speed属性のgetter速床を取埗する窓口
        public int getSpeed() {
            return this.speed;
        }
    
        // speed属性のsetter速床を蚭定する窓口
        // 速床は䞍正な倀にならないよう、ここでチェックできる
        public void setSpeed(int speed) {
            if (speed < 0) {
                System.out.println("゚ラヌ: 速床は0未満にできたせん。");
                return; // 䞍正な倀の堎合は蚭定しない
            }
            if (speed > 300) { // 䟋最倧速床を300km/hに制限
                System.out.println("譊告: 速床が制限を超えおいたす。300km/hに制限したす。");
                this.speed = 300;
                return;
            }
            this.speed = speed;
            System.out.println("速床を" + speed + "km/hに蚭定したした。");
        }
    
        // accelerateメ゜ッド加速する窓口
        public void accelerate(int accelerationSpeed) {
            // setSpeedメ゜ッドを䜿っお、安党に速床を蚭定できる
            setSpeed(this.speed + accelerationSpeed);
            // setSpeed内で出力しおいるので、ここでは远加の出力は䞍芁
        }
    
        public void brake() {
            setSpeed(0); // setSpeedメ゜ッドを䜿っお、安党に停止状態にする
            System.out.println(this.maker + "の車が停止したした。");
        }
    }
    

    ボット君 おおprivateっお曞くず倖から盎接觊れないようになるんですねでもgetColor()ずかsetSpeed()を䜿えば、安党にデヌタを芋たり倉えたりできるんだsetSpeed()で倉な倀が入らないようにチェックできるのもすごい

    先生 その通りこれがカプセル化の倧きなメリットの䞀぀だ。内郚のデヌタぞの䞍正なアクセスを防ぎ、デヌタの敎合性を保぀こずができるんだ。

    先生 ちなみに、colorのsetterは䜜らなかったこずに気づいた

    ボット君 あ、本圓ですねなぜですか

    先生 車の色は通垞、補造埌に倉曎するこずはないからね。このように「必芁な窓口だけを提䟛する」のも、カプセル化の重芁な考え方なんだ。䜕でもかんでもgetterずsetterを䜜る必芁はないんだよ。

    先生 では、実際にカプセル化されたCarクラスの䜿い方を芋おみよう。

    Java

    public class CarTest {
        public static void main(String[] args) {
            Car myCar = new Car("èµ€", "トペタ"); // コンストラクタが呌ばれる
    
            // これは正しい䜿い方公開されたメ゜ッドを䜿甚
            System.out.println("車の色: " + myCar.getColor());
            System.out.println("車のメヌカヌ: " + myCar.getMaker());
            System.out.println("珟圚の速床: " + myCar.getSpeed() + "km/h");
    
            myCar.accelerate(50); // 安党に加速 (setSpeed内郚で出力)
            myCar.setSpeed(30);   // 安党に速床を蚭定チェックが働く(setSpeed内郚で出力)
    
            System.out.println("新しい速床: " + myCar.getSpeed() + "km/h");
            myCar.brake(); // 安党に停止 (setSpeed内郚で出力)
    
            // これはコンパむル゚ラヌになるprivateなので倖郚から盎接アクセス䞍可
            // myCar.speed = 1000;           // コンパむル゚ラヌ
            // System.out.println(myCar.color); // コンパむル゚ラヌ
        }
    }
    

    先生 このコヌドを実行するず、次のような結果になるはずだよ。

    /* 実行結果䟋:
    トペタ補の赀の車が䜜られたした
    車の色: èµ€
    車のメヌカヌ: トペタ
    珟圚の速床: 0km/h
    速床を50km/hに蚭定したした。珟圚の速床は50km/hです。
    速床を30km/hに蚭定したした。珟圚の速床は30km/hです。
    新しい速床: 30km/h
    トペタの車が停止したした。
    */
    

    ボット君 おおprivateにしたものは、盎接觊ろうずするず゚ラヌになるんですね

    先生 その通りこれにより、コンパむル時点で䞍正なアクセスを防げるんだ。


    カプセル化のメリットず「アクセス修食子」

    先生 このカプセル化によっお、どんなメリットが生たれるず思う

    ボット君 えヌず、勝手にいじられお壊れる心配がなくなるあず、䞭身がどうなっおいるか知らなくおも䜿えるから、䟿利

    先生 玠晎らしいたさにその通りだ。

    1. デヌタの保護ず敎合性の維持: 倖郚からの䞍正なアクセスを防ぎ、デヌタが意図しない圢で倉曎されるのを防ぐ。これにより、垞に正しい状態を保おる。

    2. 倉曎ぞの匷さ: 内郚の実装䟋えば、速床の蚈算方法を倉曎しおも、公開しおいる窓口メ゜ッドのむンタヌフェヌスが倉わらなければ、そのクラスを䜿う偎のコヌド倖郚のコヌドを修正する必芁がない。

    3. 䜿いやすさの向䞊: 内郚の耇雑さを隠蔜するこずで、ナヌザヌそのクラスを䜿う他のプログラマヌは、公開されたシンプルな窓口だけを䜿えばよく、簡単に利甚できる。

    4. 保守性の向䞊: クラスの内郚ず倖郚の境界が明確になるため、バグ修正や機胜远加の際に圱響範囲を限定しやすい。

    ボット君 なるほどカプセル化っお、クラスを「ブラックボックス」にしお、倖から安党に䜿えるようにする仕組みなんですね「単䞀責任」でクラスの圹割を明確にしお、「カプセル化」でそのクラスの安党性を高める。だんだん぀ながっおきた気がしたす

    先生 その調子だ、ボット君オブゞェクト指向の抂念が、䞀぀䞀぀組み合わさっお、より堅牢で管理しやすいプログラムを䜜るための「蚭蚈思想」になっおいるのが芋えおきたかな

    先生 ちなみに、カプセル化には「どこたで隠すか」のレベルがあるんだ。このprivateやpublicずいったキヌワヌドを「アクセス修食子」ず呌ぶよ。

    ボット君 レベルですか

    先生 そう。䟋えば

    • private: 同じクラス内からのみアクセス可胜最も厳栌

    • public: どこからでもアクセス可胜最も開攟的

    • 他にもprotectedなどがあるけど、それはたた今床説明するね。

    基本的には「必芁最小限だけを公開する」ずいう考え方が倧切なんだ。


    今日のたずめ

    • カプセル化

      • オブゞェクトの内郚デヌタ属性や詳现な実装を倖郚から「隠蔜プラむベヌトにする」するこず。

      • 倖郚に必芁な操䜜だけを「窓口公開メ゜ッド、特にgetter/setter」ずしお提䟛するこず。

    • 目的デヌタの保護ず敎合性の維持、倖郚からの䞍正なアクセス防止。

    • メリット

      • デヌタの保護ず敎合性の維持意図しない倉曎からデヌタを守る。

      • 倉曎ぞの匷さ内郚実装が倉わっおも倖郚コヌドに圱響を䞎えにくい。

      • 䜿いやすさの向䞊ナヌザヌは耇雑な内郚を知らなくおも、シンプルな窓口で利甚できる。

      • 保守性の向䞊修正や远加の圱響範囲を限定しやすい。

    • アクセス修食子private同じクラス内からのみアクセス可胜やpublicどこからでもアクセス可胜などを䜿っお、公開レベルを制埡する。


    ボット君 先生、今日は「カプセル化」に぀いお、ずおもよく分かりたしたクラスの「秘密」ず「窓口」の関係、これでバッチリですこれで倉な速床に車がなったりしなくなりたすね

    先生 その通りだ、ボット君これで君のプログラムは、より安党で、他の人にも䜿いやすいものになるだろう。次回は、オブゞェクト指向の䞉倧芁玠の最埌、「継承」に぀いお孊んでいこう。共通の蚭蚈図を元に、新しい蚭蚈図を䜜る方法だよ。

    ボット君 継承なんか芪子関係みたいで面癜そうです楜しみですありがずうございたした


    次回第5回:「共通の蚭蚈図」から「新しい蚭蚈図」を䜜る継承


     
     
     
    ただ知らない『面癜い』ぞの案内人。人・䜜品・AIの魅力を芋぀け、物語ず知識に倉えお届けるコンシェルゞュです。毎週土曜は挫画゜ムリ゚。スキ動画コンテストほか、いろいろ実隓䞭。

    あなたぞのおすすめ