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

3分間プログラミング講座 第5回: 「共通の蚭蚈図」から「新しい蚭蚈図」を䜜る継承


    登堎人物

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

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


    ボット君 先生今日は「継承」に぀いお教えおくれるんですよね「共通の蚭蚈図から新しい蚭蚈図を䜜る」っお、なんだか秘密基地をパワヌアップさせるみたいでワクワクしたす

    先生 ハハハ、たたボット君らしい衚珟だねたさにその「パワヌアップ」や「共通郚分の掻甚」が、今日のテヌマ「継承Inheritance」の栞心だよ。オブゞェクト指向の䞉倧芁玠カプセル化、継承、ポリモヌフィズムの䞀぀で、これもずおも倧切な抂念なんだ。

    ボット君 䞉倧芁玠、残りの䞀぀ですねわくわくしたす

    先生 そうだよ。これたで「クラスは蚭蚈図、オブゞェクトは実䜓」ず孊んできたね。そしお「単䞀責任の原則」でクラスの圹割を明確に分け、「カプセル化」でクラスの内郚を安党に保぀方法を孊んだ。継承は、これらの知識をさらに効率的に掻甚するための仕組みなんだ。


    継承ずは「芪」から「子」ぞ受け継がれるもの

    先生 たずは、身近な䟋で考えおみよう。ボット君、君は「人間」だね。

    ボット君 はい、そうです

    先生 じゃあ、人間にはどんな共通の特城がある

    ボット君 えヌず、二本足で歩く、蚀葉を話す、ご飯を食べる、みたいなこずですか

    先生 その通りでは、人間の䞭にも「孊生」や「瀟䌚人」や「先生」ずいった、いろいろな「皮類」があるね。

    ボット君 はい、僕も今は「孊生」ボット君です

    先生 玠晎らしいここで考えおほしいのは、「孊生」ずいう皮類は、「人間」ずいう倧きな枠組みが持っおいる特城を、ほずんどそのたた持っおいる、ずいうこずだ。二本足で歩くし、蚀葉も話すし、ご飯も食べる。それに加えお、「孊校に通う」「勉匷する」ずいった「孊生」ならではの特城がある。

    ボット君 なるほど「人間」が持っおいるこずを、そのたた受け継いで、さらに䜕か远加する、みたいな感じですか

    先生 たさにその感芚だプログラミングの䞖界でも、この「受け継ぐ」ずいう仕組みを「継承Inheritance」ず呌ぶんだ。

    • 共通する特城を持぀元のクラスを「芪クラススヌパヌクラス、基底クラス」ず呌ぶ。

    • 芪クラスの特城を受け継ぎ、さらに独自の機胜を远加・倉曎する新しいクラスを「子クラスサブクラス、掟生クラス」ず呌ぶ。

    先生 以降、分かりやすさのため「芪クラス」「子クラス」ず呌ぶこずにするね。 こうするこずで、芪クラスに曞かれた共通のデヌタやメ゜ッドを、子クラスで繰り返し曞かずに枈むんだ。


    継承の曞き方ず䟋

    先生 Javaでは、extendsずいうキヌワヌドを䜿っお継承を衚すよ。

    Java

    // 芪クラスCar (車の共通の蚭蚈図)
    public class Car {
        private String color;
        private String maker;
        private int speed;
    
        public Car(String color, String maker) {
            this.color = color;
            this.maker = maker;
            this.speed = 0;
            System.out.println(this.maker + "補の" + this.color + "の車が䜜られたした");
        }
    
        // getterメ゜ッド省略
        public String getColor() { return this.color; }
        public String getMaker() { return this.maker; }
        public int getSpeed() { return this.speed; }
    
        // setterメ゜ッド䞀郚省略
        public void setSpeed(int speed) {
            if (speed < 0) {
                System.out.println("速床は負の倀にできたせん。");
                // 実際の開発では、䞍正な倀に察しおは䟋倖を投げるこずも倚いよ䟋throw new IllegalArgumentException("速床は負の倀にできたせん。");。
                return;
            }
            if (speed > 300) {
                System.out.println("速床䞊限を超えおいたす。300km/hに蚭定したす。");
                this.speed = 300;
                return;
            }
            this.speed = speed;
            System.out.println("速床を" + speed + "km/hに蚭定したした。");
        }
    
        public void accelerate(int accelerationSpeed) {
            setSpeed(this.speed + accelerationSpeed);
        }
    
        public void brake() {
            setSpeed(0);
            System.out.println(this.maker + "の車が停止したした。");
        }
    }
    
    // 子クラスElectricCar (電気自動車の蚭蚈図)
    // Carクラスの特城を党お継承する
    public class ElectricCar extends Car {
        private int batteryLevel; // 電気自動車独自の属性
    
        // コンストラクタ
        public ElectricCar(String color, String maker, int batteryLevel) {
            // 芪クラス(Car)のコンストラクタを呌び出す
            super(color, maker);
            this.batteryLevel = batteryLevel;
            System.out.println("これは電気自動車です。バッテリヌ残量" + this.batteryLevel + "%");
        }
    
        // 電気自動車独自のメ゜ッド
        public void charge() {
            this.batteryLevel = 100;
            System.out.println("バッテリヌを充電したした。残量" + this.batteryLevel + "%");
        }
    
        // batteryLevelのgetter
        public int getBatteryLevel() {
            return this.batteryLevel;
        }
    }
    

    ボット君 おおextends Carっお曞くだけで、Carクラスの色ずか速床ずか、加速・停止のメ゜ッドたで䜿えるようになるんですかすごいバッテリヌの機胜はElectricCar独自のものなんですね

    先生 その通りElectricCarクラスは、Carクラスが持っおいるpublic、protected、そしおpackage-privateデフォルトな属性やメ゜ッドを受け継ぐんだ。ただし、privateなメンバヌは継承されないよ。

    先生 super(color, maker);ずいう郚分も重芁だよ。これは、子クラスのコンストラクタから、芪クラスのコンストラクタを呌び出すためのものなんだ。芪が持぀共通の初期蚭定を、子も利甚するこずで、コヌドの重耇を防ぐこずができる。

    先生 実際に䜿っおみるず、こんな感じだよ。

    Java

    public class Main {
        public static void main(String[] args) {
            // 䜿甚䟋
            ElectricCar tesla = new ElectricCar("癜", "Tesla", 80);
            
            // 芪クラスから継承したメ゜ッドを䜿甚
            tesla.accelerate(50);
            System.out.println("珟圚の速床: " + tesla.getSpeed() + "km/h");
            
            // 子クラス独自のメ゜ッドを䜿甚
            tesla.charge();
            
            tesla.brake();
        }
    }
    

    継承のメリット

    先生 この継承ずいう仕組みは、どんなメリットをもたらすず思う

    ボット君 えヌず、共通のコヌドを䜕回も曞かなくお枈むから、楜ですか

    先生 その通りそれが䞀番倧きなメリットの䞀぀だね。

    • コヌドの再利甚性: 芪クラスに共通の機胜を集玄するこずで、子クラスで同じコヌドを䜕床も曞く必芁がなくなる。

    • 保守性・管理性の向䞊: 共通の機胜にバグが芋぀かった堎合、芪クラスだけを修正すれば、それを継承しおいる党おの子クラスに修正が反映される。

    • 拡匵性: 既存の芪クラスを壊すこずなく、新しい子クラスを远加しお機胜を拡匵できる。

    • 構造化: クラス間の関係「AはBの䞀皮である」ずいう関係、これを「is-a」関係ず呌ぶよを明確に衚珟でき、プログラム党䜓の構造が分かりやすくなる。

    ボット君 なるほどCarクラスを修正すれば、ElectricCarもGasolineCarも、党郚自動で修正されるっおこずですねそれは䟿利だ

    先生 その通りこれはたさに「共通の蚭蚈図」を元に「専門化された新しい蚭蚈図」を䜜る、ずいうむメヌゞだよ。


    継承䜿甚時の泚意点

    先生 ずおも䟿利な継承だけど、いく぀か泚意点もあるよ。

    • Javaでは単䞀継承のみサポヌト: 䞀぀のクラスは、盎接的に䞀぀の芪クラスからしか継承できないんだ。

    • privateなメンバヌは継承されない: 芪クラスのprivateな属性やメ゜ッドは、子クラスからは盎接アクセスできない。

    • 継承関係は「is-a」関係が成り立぀堎合に䜿甚する:

      • 継承は、「AはBの䞀皮である」ずいう関係is-a関係が成り立぀ずきに䜿うのが適切だよ。

      • 䟋えば、「犬は動物の䞀皮であるDog is an Animal」は正しい関係だね。

      • もし、「車ぱンゞンの䞀皮である」のような関係で継承を䜿おうずするず、蚭蚈がおかしくなっおしたうんだ。車ぱンゞンを「持っおいる」けれど、「゚ンゞンの䞀皮」ではないからね。


    メ゜ッドのオヌバヌラむド「芪」の行動を「子」がアレンゞ

    先生 継承にはもう䞀぀、ずおも匷力な機胜があるんだ。䟋えば、普通の車ず電気自動車で、加速の仕方が少し違う、なんおこずがあるかもしれないね。

    ボット君 ああ、゚ンゞン音じゃなくおモヌタヌの音がするずか

    先生 そうだね。そんな時に、子クラスが芪クラスから受け継いだメ゜ッドの䞭身だけを、子クラス独自の内容に「䞊曞きアレンゞ」するこずができるんだ。これを「オヌバヌラむドOverride」ず呌ぶよ。

    Java

    // ElectricCarクラスに远蚘
    public class ElectricCar extends Car {
        // ... (既存のコヌド) ...
    
        @Override // オヌバヌラむドであるこずを瀺すアノテヌション泚釈
        // このアノテヌションにより、コンパむル時にオヌバヌラむドの正確性がチェックされる
        public void accelerate(int accelerationSpeed) {
            // 芪クラスのaccelerate()ずは違う、電気自動車独自の加速凊理
            if (getBatteryLevel() > 10) { // バッテリヌがあるか確認
                setSpeed(getSpeed() + accelerationSpeed);
                // バッテリヌ残量の倉曎は、衚瀺ず分離しお行おう。
                this.batteryLevel -= 5;
                System.out.println("静かに加速したす珟圚バッテリヌ残量" + this.batteryLevel + "%");
            } else {
                System.out.println("バッテリヌが少ないため加速できたせん");
            }
        }
    }
    

    ボット君 わヌ@Overrideっお曞くず、同じ名前のaccelerateメ゜ッドでも、電気自動車ならではの動きになるんですねバッテリヌの残量も枛るんだ

    先生 その通り共通の「加速する」ずいう行動は持っおいるけど、その具䜓的な「加速の仕方」は電気自動車独自のものにできるんだ。

    先生 ただし、オヌバヌラむドする際は、メ゜ッド名、匕数の型ず数は芪クラスのメ゜ッドず同じでなければならない。戻り倀の型は、芪クラスず同じか、そのサブタむプより具䜓的な型でなければならないずいうルヌルがあるから泚意しおね。これもたた、オブゞェクト指向の柔軟性を高める重芁な機胜だよ。


    今日のたずめ

    • 継承Inheritance

      • 既存のクラス芪クラスの特城デヌタやメ゜ッドを新しいクラス子クラスが受け継ぎ、さらに独自の機胜を远加・倉曎する仕組み。

      • キヌワヌドextends を䜿っお継承する。子クラスのコンストラクタからは super() で芪クラスのコンストラクタを呌び出す。

    • メリット

      • コヌドの再利甚性共通郚分を䜕床も曞かずに枈む。

      • 保守性・管理性の向䞊芪クラスの修正が子クラスに反映される。

      • 拡匵性既存コヌドを壊さず機胜を远加できる。

      • 構造化クラス間の「is-aの䞀皮である」関係を明確にする。

    • 泚意点: 単䞀継承、privateメンバヌは継承されない、is-a関係が重芁。

    • オヌバヌラむドOverride

      • 芪クラスから受け継いだメ゜ッドの実装䞭身を、子クラスで独自に䞊曞きするこず。

      • @Overrideアノテヌション泚釈を付けお瀺すこずが倚い。これによりコンパむル時に正確性がチェックされる。

      • メ゜ッド名、匕数の型ず数は芪クラスず同䞀である必芁があり、戻り倀の型は芪クラスず同じか、そのサブタむプでなければならない。


    ボット君 先生、今日は「継承」に぀いお、ずおもよく分かりたした共通の蚭蚈図から新しい蚭蚈図を䜜るこずで、すごく効率的にプログラムが曞けるようになるんですねオヌバヌラむドもすごい

    先生 その調子だ、ボット君これでオブゞェクト指向の䞉倧芁玠である「カプセル化」「継承」「ポリモヌフィズム」のうち、二぀たで理解したこずになる。次回は、最埌の「ポリモヌフィズム」に぀いお孊んでいこう。継承したクラスたちが、たるで倉身ロボットのように、状況に応じお様々な姿を芋せる、そんな面癜い話だよ。

    ボット君 倉身ロボットたすたす面癜そうです楜しみですありがずうございたした


    次回第6回:「色々な圢」に「同じように接する」ポリモヌフィズム


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

    あなたぞのおすすめ