工業製造
産業用モノのインターネット | 工業材料 | 機器のメンテナンスと修理 | 産業プログラミング |
home  MfgRobots >> 工業製造 >  >> Industrial programming >> C言語

C#のインターフェース:堅牢なオブジェクト指向設計のための契約定義

インターフェースとは、インターフェースを継承するすべてのクラスが従うべき構文上の契約として定義されます。インターフェースは構文契約の「何(What)」の部分を定義し、派生クラスが「どう(How)」の部分を定義します。

インターフェースはプロパティ、メソッド、イベントを定義し、これらはインターフェースのメンバーとなります。インターフェースにはメンバーの宣言のみが含まれます。メンバーを定義するのは派生クラスの責任です。これにより、派生クラスが従うべき標準的な構造を提供することがよくあります。

抽象クラスも一定程度同じ目的を果たしますが、基底クラスでわずかなメソッドのみを宣言し、派生クラスで機能を実装する場合に主に使用されます。

インターフェースの宣言

インターフェースはinterfaceキーワードで宣言します。クラス宣言に似ています。インターフェースのステートメントはデフォルトでpublicです。

public interface ITransactions {
    // インターフェースメンバー
    void ShowTransaction();
    double GetAmount();
}

慣習として、インターフェース名にはIプレフィックスを付けます(IComparable, IDisposableなど)。

インターフェースの実装例

using System;
namespace InterfaceApplication {
    public interface ITransactions {
        void ShowTransaction();
        double GetAmount();
    }
    
    public class Transaction : ITransactions {
        private string tCode;
        private string date;
        private double amount;
        
        public Transaction() {
            tCode = " "; date = " "; amount = 0.0;
        }
        
        public Transaction(string c, string d, double a) {
            tCode = c; date = d; amount = a;
        }
        
        public double GetAmount() => amount;
        
        public void ShowTransaction() {
            Console.WriteLine("Transaction: {0}", tCode);
            Console.WriteLine("Date: {0}", date);
            Console.WriteLine("Amount: {0}", GetAmount());
        }
    }
    
    class Tester {
        static void Main(string[] args) {
            Transaction t1 = new Transaction("001", "8/10/2012", 78900.00);
            Transaction t2 = new Transaction("002", "9/10/2012", 451900.00);
            
            t1.ShowTransaction();
            t2.ShowTransaction();
            Console.ReadKey();
        }
    }
}

実行結果:

Transaction: 001
Date: 8/10/2012
Amount: 78900
Transaction: 002
Date: 9/10/2012
Amount: 451900

インターフェースの重要な特徴

明示的なインターフェース実装

同じシグネチャのメンバーを持つ複数のインターフェースを実装する場合、またはクラスの公開APIから隠蔽したい場合に使用します。

interface IFirst { void Method(); }
interface ISecond { void Method(); }

class MyClass : IFirst, ISecond {
    // 明示的実装(インターフェース名.メンバー名)
    void IFirst.Method() { Console.WriteLine("IFirst.Method"); }
    void ISecond.Method() { Console.WriteLine("ISecond.Method"); }
    
    // 通常の公開メソッドとしても定義可能
    public void Method() { Console.WriteLine("Public Method"); }
}

// 使用
MyClass obj = new MyClass();
obj.Method();                    // "Public Method"
((IFirst)obj).Method();         // "IFirst.Method"
((ISecond)obj).Method();        // "ISecond.Method"

デフォルト実装(C# 8.0以降)

C# 8.0から、インターフェースにメソッドのデフォルト実装を提供できます。

interface ILogger {
    void Log(string message);
    
    // デフォルト実装
    void LogError(string error) {
        Log($"ERROR: {error}");
    }
    
    // 静的メソッドも可能
    static void LogStatic(string msg) => Console.WriteLine($"STATIC: {msg}");
}

インターフェース vs 抽象クラス

特徴インターフェース抽象クラス
多重実装可能(複数実装可)不可(単一継承のみ)
実装の有無原則宣言のみ(C# 8.0+でデフォルト実装可)実装を持てる
フィールド持てない(定数のみ)持てる
コンストラクタ不可可能
アクセス修飾子すべてpublic(C# 8.0+でprivate static等可)自由
用途「できること」の契約(CAN-DO)「であること」の共有(IS-A)

よく使用される標準インターフェース

インターフェース目的主なメンバー
IDisposableリソース解放Dispose()
IComparable<T>並べ替え比較CompareTo(T)
IEquatable<T>値の等価性Equals(T)
IEnumerable<T>列挙/反復GetEnumerator()
ICloneable複製Clone()
IAsyncDisposable非同期リソース解放DisposeAsync()

依存性逆転の原則(DIP)とインターフェース

高レベルモジュールは低レベルモジュールに依存すべきではなく、両方とも抽象(インターフェース)に依存すべきです。


// 悪い例:具象クラスに依存
class UserService {
    private SqlRepository repo = new SqlRepository();  // 具象依存
}

// 良い例:インターフェースに依存
class UserService {
    private readonly IUserRepository repo;  // 抽象依存
    
    public UserService(IUserRepository repo) {
        this.repo = repo;  // DIコンテナから注入
    }
}

ベストプラクティス

C言語

  1. 長い driveway 向けの信頼性の高いワイヤレスセンサー - Raspberry Piとの簡単統合
  2. SPICEでのコマンドラインインターフェースの使い方
  3. C#インターフェイスをマスターする:定義、実装、実践的なユースケース
  4. C++インターフェース完全理解:抽象クラスと純粋仮想関数
  5. Javaインターフェース完全ガイド:概念、実装、ベストプラクティス
  6. Javaコレクションフレームワーク入門:主要インターフェースと実装クラス
  7. Java Collectionインターフェース:核心概念と必須メソッド
  8. Java NavigableSetインターフェースをマスター:ナビゲーション、ソート、実践例
  9. Javaラムダ式完全ガイド:基礎からStream APIまで
  10. Javaインターフェース完全ガイド: 定義・実装・多重継承・タグインターフェース
  11. Java 9プライベートインターフェースメソッド:カプセル化とコード再利用を強化