【C#】継承とインターフェース

C#

本記事では継承とインターフェースの概要と使い分けについて記述します。

継承

概要

既存のクラスの特徴をもつ新しいクラスをつくる仕組みです。

(例)過去に「動物」クラスを作ったことがあるとして、その特徴を継承した「犬」クラスと「猫」クラスを作る。

サンプル

動物と犬猫の継承関係のサンプルです。この例では「動物は鳴くもの」という特徴を持っていて、犬と猫も同様の特徴(機能)を受け継ぎます。

using System;
using System.Collections.Generic;

// 動物を表す基本クラス
public class Animal
{
    // プロパティ
    public string Name { get; private set; }

    // コンストラクタ
    public Animal(string name)
    {
        Name = name;
    }

    // メソッド
    public virtual void MakeSound()
    {
        Console.WriteLine("動物の声を出す");
    }
}

// 犬クラス(Animalクラスを継承)
public class Dog : Animal
{
    // コンストラクタ
    public Dog(string name)
        : base(name)
    {
    }

    // メソッドのオーバーライド
    public override void MakeSound()
    {
        Console.WriteLine($"{Name}の鳴き声: ワン!");
    }
}

// 猫クラス(Animalクラスを継承)
public class Cat : Animal
{
    // コンストラクタ
    public Cat(string name)
        : base(name)
    {
    }

    // メソッドのオーバーライド
    public override void MakeSound()
    {
        Console.WriteLine($"{Name}の鳴き声: ニャーン!");
    }
}

class Program
{
    static void Main()
    {
        Dog dog = new Dog("ポチ");  // 犬オブジェクトを生成
        Cat cat = new Cat("たま");  // 猫オブジェクトを生成

        //-------------------------------
        // 動物を個別に鳴かせる
        //-------------------------------
        Console.WriteLine("-- 個別に鳴かせる --");
        dog.MakeSound();   // 犬クラスを鳴かせる
        cat.MakeSound();   // 猫クラスを鳴かせる

        //-------------------------------
        // 動物をまとめて鳴かせる
        //-------------------------------
        Console.WriteLine("-- まとめて鳴かせる --");

        // 動物という括りでリストにまとめる
        List<Animal> animalList = new List<Animal>();
        animalList.Add(dog);
        animalList.Add(cat);

        // リストに含まれる動物をすべて鳴かせる
        foreach (Animal animal in animalList)
        {
            animal.MakeSound();
        }
    }
}

実行結果

ポチの鳴き声: ワン!
たまの鳴き声: ニャーン!

インターフェース

概要

異なるクラスに共通の機能を持たせる場合に使用します。それぞれのクラスが共通のベースクラスを持つ必要はありません。

(例)「電気自動車」クラスと「テレビ」クラスは、どちらも「電源をONする」というインターフェース(機能)を外部に公開する。

サンプル

using System;
using System.Collections.Generic;

// 電源スイッチのオン/オフ機能を追加するインターフェース
public interface ISwitchable
{
    void TurnOn();
    void TurnOff();
}

// 電気自動車クラス
public class ElectricCar : ISwitchable
{
    public void Drive()
    {
        Console.WriteLine("電気自動車:走ります。");
    }
    // 電源スイッチをオンするインターフェース
    public void TurnOn()
    {
        Console.WriteLine("電気自動車:スイッチをオンにしました。");
    }
    // 電源スイッチのオフするインターフェース
    public void TurnOff()
    {
        Console.WriteLine("電気自動車:スイッチをオフにしました。");
    }
}

// テレビクラス
public class Television : ISwitchable
{
    public void Operate()
    {
        Console.WriteLine("テレビ:映像を映します。");
    }
    // 電源スイッチをオンするインターフェース
    public void TurnOn()
    {
        Console.WriteLine("テレビ:スイッチをオンにしました。");
    }
    // 電源スイッチのオフするインターフェース
    public void TurnOff()
    {
        Console.WriteLine("テレビ:スイッチをオフにしました。");
    }
}

class Program
{
    static void Main()
    {
        // 電気自動車
        ElectricCar electricCar = new ElectricCar();
        // テレビ
        Television television = new Television();

        //-------------------------------
        // 電源をまとめてON
        //-------------------------------
        Console.WriteLine("-- まとめて電源ON --");

        // 電源スイッチを有するオブジェクトでまとめる
        List<ISwitchable> switcableList = new List<ISwitchable>();
        switcableList.Add(electricCar);
        switcableList.Add(television);

        // リストに含まれる機器の電源をすべてONする
        foreach (ISwitchable switcable in switcableList)
        {
            switcable.TurnOn();
        }

        //-------------------------------
        // 機器を使用
        //-------------------------------
        Console.WriteLine("-- 機器を使用 --");
        electricCar.Drive();     // 電気自動車を運転
        television.Operate();    // テレビを操作
    }
}

実行結果

-- まとめて電源ON --
電気自動車:スイッチをオンにしました。
テレビ:スイッチをオンにしました。
-- 機器を使用 --
電気自動車:走ります。
テレビ:映像を映します。

継承とインターフェースの使い分け

動物→犬・猫のようにベースと派生の関係がある場合は継承、あるクラスに追加機能を与える場合はインターフェースを使うようにしています。

タイトルとURLをコピーしました