C#初心者のための基礎!ポリモーフィズムとインタフェースの使い方を解説#28

当サイトではアフィリエイト広告を利用しています。

C#初級プログラミング

ポリモーフィズムとは?

ポリモーフィズムとは、オブジェクト指向プログラミングの肝となる考え方です。この考え方ができない間は、オブジェクト指向プログラミングができていないといえます。

ポリモーフィズムとは、クラスに実装の強制を行い、クラスを使う側のコードが、実装を意識することなく、ある決まり事に沿って使用すれば、処理が行われるプログラミング手法です。

といわれても意味が分からないと思いますが、この考え方は、一度プログラムを書いて、実行してみないと、なかなか理解ができないと思います。

実装方法

ポリモーフィズムの実装を実現する方法は2種類あります。インタフェースと抽象クラスです。どちらも似たような機能ですが、多少使い方が異なります。インタフェースを使うか抽象クラスを使うべきかは、ロジックを含むかどうかで判断します。ロジックの途中を虫食い状態の抽象メソッドにして、部分的にメソッドの実装を強制する場合は抽象クラスを使います。ロジックの記述がなく、メソッドの実装の強制のみで使用する場合はインタフェースを使用します。

注意点

抽象クラスは継承を使用して派生クラスに実装を強制するため、1つの派生クラスに指定できる抽象クラスは1つまでです。インタフェースはクラスではないため、複数の指定が可能です。そのあたりも加味して、インタフェースか抽象クラスを使用するかを検討してください。

インタフェースとは?

インタフェースとは、クラスにメソッドやプロパティの実装を強制するための機能です。インタフェースを実装しているクラスは、インタフェースで指定されているメソッドやプロパティを必ず実装している必要があります。実装していない場合はコンパイルエラーになります。ちなみにインタフェースに実装部分はなく、定義だけを記述します。

インタフェースがあると何がいいの?

インタフェースで実装の強制をするため、同じインタフェースを実装しているクラスは、同一のものとして処理する記述ができます。

例えばSQLServerに接続するクラスと、Oracleに接続するクラスに同じインタフェースを実装しておけば、途中でクラスを差し替えても、動作させることができます。

サンプルコード

IDatabaseというインタフェースを作成し、Saveメソッドを定義。

namespace CS28
{
    interface IDatabase
    {
        void Save();
    }
}

IDataBaseインタフェースを実装するProductsクラス。Saveメソッドがないとコンパイルは通りません。

namespace CS28
{
    class Products : IDatabase
    {
        public void Save()
        {
            Console.WriteLine("商品マスタの登録");
        }
    }
}

IDataBaseインタフェースを実装するOrdersクラス。Saveメソッドがないとコンパイルは通りません。

namespace CS28
{
    class Orders : IDatabase
    {
        public void Save()
        {
            Console.WriteLine("発注テーブル登録");
        }
    }
}
namespace CS28
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();

            IDatabase product = new Products();
            IDatabase orders = new Orders();

            List databases = new List();
            databases.Add(product);
            databases.Add(orders);

            foreach(var val in databases)
            {
                val.Save();
            }
        }
    }
}

ポイントは「IDatabase product = new Products()」と「IDatabase orders = new Orders(); 」の部分で、右側はクラス名に対して、左側は、どちらもIDatabaseになっています。使う側は、ProductsもOrdersも意識せずにIDataBaseとして扱うことで、foreachのループの中で、何も意識することなくSaveメソッドを呼び出すことができます。インタフェースがなければ、そもそも型が異なるため同一のリストにAddすることができません。