C#のインターフェースと抽象クラスの違いを徹底解説!初心者でも分かる具体例付き

プログラミング

インターフェースと抽象クラスの違いは理解しにくいですが、この記事では、初心者の方でも理解できるように、具体例を交えながらインターフェースと抽象クラスの違いについて詳しく解説していきます。

インターフェースとは?

インターフェースは、クラスや構造体が実装すべきメソッドやプロパティの契約を定義するための仕組みです。言い換えると、インターフェースは「こういう機能を実装してくださいね」という約束を示すものです。

支払い方法を表すクラスをインターフェースで表現すると次のようになります。

public interface IPaymentMethod
{
    void Payment(decimal amount);
}

public class CreditCard : IPaymentMethod
{
    public void Payment(decimal amount)
    {
        Console.WriteLine($"クレジットカードで{amount}円を支払いました。");
    }
}

public class Cash : IPaymentMethod
{
    public void Payment(decimal amount)
    {
        Console.WriteLine($"現金で{amount}円を支払いました。");
    }
}

この例では、IPaymentMethodインターフェースを実装することで、CreditCardクラスやCashクラスは共通のメソッドPaymentを持つことが求められます。インターフェースは多重継承が可能で、複数のインターフェースを同時に実装することもできます。

抽象クラスとは?

一方、抽象クラスは、共通の機能を提供しつつ、特定のメソッドを派生クラスで実装させる仕組みです。抽象クラスでは、共通の機能やプロパティを提供しつつ、具体的な動作を派生クラスに任せることができます。

次に、抽象クラスを使った支払い方法の例を見てみましょう。

public abstract class PaymentMethod
{
    public abstract void Payment(decimal amount);

    public void PrintReceipt()
    {
        Console.WriteLine("領収書を発行しています...");
    }
}

public class CreditCard : PaymentMethod
{
    public override void Payment(decimal amount)
    {
        Console.WriteLine($"クレジットカードで{amount}円を支払いました。");
    }
}

ここで、PaymentMethodクラスはPaymentメソッドを抽象メソッドとして定義しています。このメソッドの具体的な実装は、CreditCardクラスのような派生クラスで行います。また、PaymentMethodクラスにはPrintReceiptメソッドのように、具体的な実装を持つメソッドも含めることができます。

インターフェースと抽象クラスの違い

インターフェースと抽象クラスには、それぞれ異なる特徴があります。

  • 多重継承:インターフェースは多重継承が可能です。一方で、抽象クラスは単一継承しかできません。
  • 実装の有無:インターフェースにはメソッドの実装を持たせることができませんが(C# 8.0以降はデフォルト実装が可能)、抽象クラスでは一部のメソッドを実装することができます。
  • 使用目的:インターフェースは異なるクラス間で共通の機能を強制したい場合に使用し、抽象クラスは同じ系統のクラス間で共通の基本的な機能を提供しつつ、派生クラスでの具体的な実装を強制したい場合に使用します。

どちらを使うべきか?

インターフェースと抽象クラスの使い分け方について、いくつかの具体例を挙げてみましょう。インターフェースと抽象クラスを使い分けるための一般的な指針は以下の通りです:

  • 共通の振る舞いを強制する場合(多くの異なるクラスに共通の動作を実装したい場合)—インターフェースを使用
  • 共通の機能やデータを持たせたい場合(基本的な実装を共有したい場合)—抽象クラスを使用

具体例で理解を深める

例えば、ECサイトの決済システムを考えてみましょう。すべての支払い方法が「支払う」動作を持つ必要がある場合、インターフェースを使用するのが適切です。一方、すべての支払い方法が「領収書を発行する」機能を共通化したい場合は、抽象クラスを使うと便利です。

public interface IPaymentMethod
{
    void Payment(decimal amount);
}

public abstract class PaymentMethod
{
    public int TransactionId { get; set; }

    public abstract void Payment(decimal amount);

    public void PrintReceipt()
    {
        Console.WriteLine("領収書を発行しています...");
    }
}

このように、目的に応じて使い分けることで、コードの設計がより柔軟で理解しやすいものになります。

まとめ

インターフェースと抽象クラスは、どちらもオブジェクト指向プログラミングにおいて重要な役割を持っています。インターフェースは「何をするか」を定義し、抽象クラスは「何をするか」に加えて「どうするか」を一部共有できます。適切に使い分けることで、保守性が高く拡張しやすいコードを書くことができます。

この記事を通して、インターフェースと抽象クラスの違いを理解し、どちらを使うべきか判断できるようになったでしょうか?どちらを使うべきか迷ったときは、共通の機能が必要かどうかを考えると良いでしょう。ぜひ、自分のコードに取り入れてみてください!

コメント

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