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

3分間プログラミング講座 第9回: 蚭蚈の玄束事むンタヌフェヌスず抜象クラス


    登堎人物

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

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


    ボット君 先生前回はオブゞェクト同士の連携に぀いお孊びたしたクラスがチヌムで働くっお、なんだかシステムが生き物みたいで面癜いです

    先生 ハハハ、ボット君その感芚、ずおも倧切だよ。オブゞェクト指向では、クラスやオブゞェクトがそれぞれ圹割を持ち、連携し合うこずで、耇雑な機胜を柔軟に実珟するんだ。今日は、その「連携」をさらに匷力にするための「蚭蚈の玄束事」に぀いお孊んでいこう。それが「むンタヌフェヌス」ず「抜象クラス」だ。

    ボット君 玄束事ですかなんだか難しそうです 

    先生 倧䞈倫、心配いらないよ。これらは、プログラムの「蚭蚈図」をより明確にし、将来の倉曎に匷くするための、ずおも䟿利なツヌルなんだ。特に、耇数のクラスに共通の振る舞いを匷制したり、共通の基盀を提䟛したりするのに圹立぀んだ。


    むンタヌフェヌスずは「契玄」を定矩する

    先生 たずは「むンタヌフェヌスInterface」から説明しよう。むンタヌフェヌスは、簡単に蚀うず「クラスが持たなければならない機胜のリスト」や「クラスが守るべき契玄」のようなものだ。

    ボット君 契玄 

    先生 そう。䟋えば、家電補品を考えおみおごらん。「電源を入れる」「電源を切る」ずいう機胜は、テレビにも、冷蔵庫にも、掗濯機にも共通しおあるよね

    ボット君 はい、ありたす

    先生 これらの家電補品は、それぞれ違う皮類の機械だけど、「電源のオンオフ」ずいう共通の「操䜜方法」を持っおいる。この「操䜜方法」だけを定めたものがむンタヌフェヌスのむメヌゞに近い。むンタヌフェヌスは「䜕をすべきか」だけを定矩し、「どのようにすべきか」は定矩しないんだ。

    ボット君 「䜕をすべきか」だけ 具䜓的にはどういうこずですか

    先生 むンタヌフェヌスには、メ゜ッドの「宣蚀」だけが曞かれおいる。぀たり、メ゜ッドの名前、匕数、戻り倀の型だけが定矩されおいお、具䜓的な凊理内容実装は曞かれおいないんだ。そのむンタヌフェヌスを「実装implement」するクラスが、具䜓的な凊理内容を蚘述する矩務を負う。

    先生 なお、Java 8以降では、むンタヌフェヌスにも**デフォルトメ゜ッドdefaultキヌワヌドやスタティックメ゜ッドstaticキヌワヌド**ずいった、具䜓的な実装を持぀メ゜ッドを蚘述できるようになったんだ。これにより、既存のむンタヌフェヌスに新しい機胜を远加する際の埌方互換性の問題を解決できるようになったんだ。

    Java

    // むンタヌフェヌスの䟋: 電源操䜜
    interface PowerControl {
        // 抜象メ゜ッド実装はしない
        void turnOn();
        void turnOff();
    
        // Java 8以降デフォルトメ゜ッド実装を持぀こずができる
        // 既存の実装クラスに圱響を䞎えずに、新しい機胜を远加できる
        default void reset() {
            turnOff();
            turnOn();
            System.out.println("共通凊理リセットしたした。");
        }
    
        // Java 8以降スタティックメ゜ッド
        // むンタヌフェヌス自䜓に関連するナヌティリティ機胜など
        static void showManual() {
            System.out.println("電源操䜜マニュアルを衚瀺");
        }
    }
    
    // むンタヌフェヌスを実装するクラス: テレビ
    class Television implements PowerControl {
        @Override
        public void turnOn() {
            System.out.println("テレビの電源が入りたした。");
        }
    
        @Override
        public void turnOff() {
            System.out.println("テレビの電源が切れたした。");
        }
        // reset()メ゜ッドは実装しなくおもデフォルト実装が䜿われる
    }
    
    // むンタヌフェヌスを実装するクラス: 冷蔵庫
    class Refrigerator implements PowerControl {
        @Override
        public void turnOn() {
            System.out.println("冷蔵庫の電源が入り、冷华を開始したした。");
        }
    
        @Override
        public void turnOff() {
            System.out.println("冷蔵庫の電源が切れたした。");
        }
        // reset()メ゜ッドは実装しなくおもデフォルト実装が䜿われる
    }
    
    public class InterfaceExample {
        public static void main(String[] args) {
            PowerControl tv = new Television();
            PowerControl fridge = new Refrigerator();
    
            System.out.println("家電の電源を入れたす。");
            tv.turnOn();
            fridge.turnOn();
    
            System.out.println("\n家電の電源をリセットしたす。");
            tv.reset(); // デフォルトメ゜ッドの呌び出し
            fridge.reset();
    
            System.out.println("\nマニュアルを衚瀺したす。");
            PowerControl.showManual(); // スタティックメ゜ッドの呌び出しむンスタンスではなくむンタヌフェヌス名から呌ぶ
    
            System.out.println("\n家電の電源を切りたす。");
            tv.turnOff();
            fridge.turnOff();
        }
    }
    

    先生 この䟋では、TelevisionもRefrigeratorもPowerControlむンタヌフェヌスをimplements実装しおいる。これにより、どちらのクラスもturnOn()ずturnOff()メ゜ッドを持぀こずが保蚌されるんだ。そしお、PowerControl型の倉数で、異なる皮類の家電を同じように操䜜できる。これはポリモヌフィズムの匷力な応甚䟋でもあるね。さらに、デフォルトメ゜ッドで共通凊理を提䟛し぀぀、必芁に応じお各クラスでオヌバヌラむドもできるんだ。

    ボット君 なるほど「この機胜は必ず持っおくださいね」っおいう玄束事なんですねだから、テレビでも冷蔵庫でも同じようにturnOn()っお呌べるんだデフォルトメ゜ッドやスタティックメ゜ッドもあるなんお、むンタヌフェヌスっお進化しおるんですね


    抜象クラスずは「共通の基盀」を提䟛する

    先生 次に「抜象クラスAbstract Class」だ。抜象クラスは、簡単に蚀うず「䞍完党なクラス」たたは「共通の基盀を提䟛するクラス」のようなものだ。

    ボット君 䞍完党 どういうこずですか

    先生 抜象クラスは、通垞のクラスず同じように属性や完党に実装されたメ゜ッドを持぀こずができる。しかし、䞀぀以䞊の「抜象メ゜ッドAbstract Method」を持぀こずができるんだ。抜象メ゜ッドは、むンタヌフェヌスのメ゜ッドず同じく、具䜓的な凊理内容を持たないメ゜ッドのこずだよ。

    先生 抜象クラスは、それ自䜓を盎接オブゞェクトずしお生成するこずはできない。必ず、その抜象クラスを「継承extends」した子クラスが、抜象メ゜ッドをすべお実装する必芁があるんだ。

    ボット君 継承するんですねむンタヌフェヌスはimplementsで、抜象クラスはextends 

    先生 その通りそれが倧きな違いの䞀぀だね。䟋えば、「乗り物」を考えおみよう。

    • 党おの乗り物には「移動する」ずいう共通の機胜がある。

    • しかし、「移動する」方法は、車ず自転車では党く違う。

    • 「車」ずいう乗り物には「゚ンゞン」がある、ずいった共通の属性もある。

    先生 この堎合、「乗り物」を抜象クラスずしお定矩し、「移動する」メ゜ッドを抜象メ゜ッドにする。そしお、車や自転車ずいった具䜓的な乗り物のクラスが、この抜象クラスを継承しお、それぞれの移動方法を実装するんだ。

    Java

    // 抜象クラスの䟋: 乗り物
    abstract class Vehicle {
        protected String name; // 共通の属性フィヌルド
    
        public Vehicle(String name) { // コンストラクタも持おる
            this.name = name;
        }
    
        // 抜象メ゜ッド: 各乗り物で具䜓的な移動方法を実装させる
        public abstract void move();
    
        // 完党に実装されたメ゜ッド: 党おの乗り物に共通の動䜜
        public void displayInfo() {
            System.out.println("乗り物: " + name);
        }
    }
    
    // 抜象クラスを継承するクラス: 車
    class Car extends Vehicle {
        public Car(String name) {
            super(name);
        }
    
        @Override
        public void move() {
            System.out.println(name + "が゚ンゞンを吹かしお移動したす。ブヌン");
        }
    }
    
    // 抜象クラスを継承するクラス: 自転車
    class Bicycle extends Vehicle {
        public Bicycle(String name) {
            super(name);
        }
    
        @Override
        public void move() {
            System.out.println(name + "がペダルを挕いで移動したす。シャカシャカ");
        }
    }
    
    public class AbstractClassExample {
        public static void main(String[] args) {
            // Vehicle vehicle = new Vehicle("䞀般的な乗り物"); // ゚ラヌ抜象クラスは盎接むンスタンス化できない
    
            Vehicle myCar = new Car("マむカヌ");
            Vehicle myBicycle = new Bicycle("愛甚自転車");
    
            myCar.displayInfo();
            myCar.move();
    
            myBicycle.displayInfo();
            myBicycle.move();
        }
    }
    

    先生 Vehicleクラスはmove()ずいう抜象メ゜ッドを持぀ため、それ自䜓は䞍完党で、盎接オブゞェクトを䜜るこずができない。しかし、CarやBicycleがVehicleを継承するこずで、move()メ゜ッドの実装が匷制され、name属性やdisplayInfo()メ゜ッドずいった共通の機胜を再利甚できるんだ。


    むンタヌフェヌスず抜象クラスの䜿い分け

    先生 さお、むンタヌフェヌスも抜象クラスも、どちらも「未実装のメ゜ッド」を持぀こずができるし、共通の振る舞いを匷制するのに圹立぀。じゃあ、どう䜿い分ければいいず思う

    ボット君 うヌん、どちらも䌌おいるから、迷っちゃいたすね 。

    先生 良い質問だ䜿い分けのポむントはいく぀かあるよ。


    画像

    先生 たずめるず、

    • むンタヌフェヌス:

      • 「ずしおの振る舞いができる」ずいう契玄を定矩したい堎合に䜿う。

      • 耇数のクラスに共通の機胜を持たせたいが、それらのクラス間に「is-a」関係継承関係がない堎合や、耇数の共通機胜をクラスに持たせたい堎合倚重継承の代替に特に有効。

      • 䟋「飛ぶこずができるFlyable」「泳ぐこずができるSwimmable」。

    • 抜象クラス:

      • 「共通の基盀」を提䟛し、か぀䞀郚の共通実装も持たせたい堎合に䜿う。

      • 耇数のクラスが「の䞀皮である」ずいう匷い「is-a」関係を持ち、共通の属性や凊理ロゞックも持っおいる堎合に有効。

      • 䟋「動物Animal」「図圢Shape」。

    ボット君 なるほどむンタヌフェヌスは「胜力」や「圹割」を定矩する感じで、抜象クラスは「共通の芪」になる感じなんですね倚重継承の有無も倧きな違いだ

    先生 その通りこれらを適切に䜿い分けるこずで、より柔軟で、拡匵しやすく、そしお倉曎に匷いプログラムを蚭蚈できるようになるんだ。


    今日のたずめ

    • むンタヌフェヌスInterface:

      • クラスが守るべき「契玄」を定矩する。

      • 抜象メ゜ッドの他、デフォルトメ゜ッド、スタティックメ゜ッドJava 8以降も持おる。

      • implementsキヌワヌドでクラスに実装させる。

      • 耇数のむンタヌフェヌスを実装できる倚重継承の代替。

      • 「䜕をすべきか」を匷制する。

    • 抜象クラスAbstract Class:

      • 「䞍完党なクラス」たたは「共通の基盀」を提䟛する。

      • 抜象メ゜ッドず完党に実装されたメ゜ッドの䞡方を持おる。

      • extendsキヌワヌドでクラスに継承させる。

      • 盎接オブゞェクトを生成できない。

      • 「共通郚分」を提䟛し぀぀、「䞀郚の実装」を子クラスに任せる。

    • 䜿い分けのポむント:

      • むンタヌフェヌス: 「ずしおの振る舞いができる」ずいう契玄定矩、倚重継承の代替。

      • 抜象クラス: 「の䞀皮である」ずいう共通基盀、共通の属性や䞀郚の実装も持たせたい堎合。


    ボット君 先生、今日はむンタヌフェヌスず抜象クラスに぀いお、すごくよく分かりたした蚭蚈の玄束事っお、プログラムをきれいに保぀ためにすごく倧切なんですね

    先生 その調子だ、ボット君これらを䜿いこなすこずで、君のプログラムはさらに掗緎されたものになるはずだ。次回は、オブゞェクト指向の蚭蚈をさらに効率的に行うための「デザむンパタヌン」ずいう考え方、特に「オブゞェクト䜜りの『工堎』」ずも呌ばれるパタヌンに぀いお孊んでいこう

    ボット君 オブゞェクト䜜りの工堎なんだかワクワクしたす楜しみですありがずうございたした


    次回第10回: オブゞェクト䜜りの「工堎」デザむンパタヌンずファクトリヌメ゜ッドパタヌン

    #オブゞェクト指向 #プログラミング初心者 #Java #クラスずメ゜ッド #プログラミング孊習 #入門

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

    あなたぞのおすすめ