[C#1]11-インタフェース

10561 ワード

インタフェースと継承
CLRは、1つのタイプに1つのベースタイプしかないことを規定し、この継承は単一の継承となる.
インタフェース継承とは、メソッド実装ではなく、インタフェース内のメソッド署名のタイプを継承することを意味し、通常は実装インタフェースと呼ばれる.インタフェースは、仮想メソッドのセットを含む抽象的なタイプにすぎず、実装は含まれません.CLRでは、インタフェースに静的メソッド、静的フィールド、定数、および静的コンストラクタを含めることができますが、CLS互換性のあるインタフェースタイプでは、プログラミング言語によっては定義またはアクセスできない静的メンバーは許可されません.C#言語は、インタフェースに静的メンバーが存在することを許可しません.
約束インタフェース名の最初のアルファベットは大文字のIである.インタフェースは複数継承できますが、実際には複数のインタフェースのタイプが実装されており、そのオブジェクトをこのインタフェースのいずれかと見なすことができます.一人で多くの能力を持っているように、彼は水泳ができて[多くの選手を見ることができます]、彼はプログラミングができます[プログラマー].値タイプは、インタフェースを実装することもできます.値タイプインスタンスをインタフェースタイプに変換すると、インタフェースは常に参照タイプとみなされ、それらの方法は常に虚メソッドであるため、箱詰めされます.箱詰めされていない値タイプにはメソッドテーブルポインタがありません.箱詰めを実行するとCLRがタイプのメソッドテーブルをクエリーできるようになり、そのダミーメソッドを呼び出すことができます.
抽象クラス:is-aの関係;インタフェース:can-doの関係.
インタフェースを使用して、箱詰め値タイプのフィールドを変更します.
public struct Location
{
    public int x, y;
 
    public void Change(int x, int y)
    {
        this.x = x;
        this.y = y;
    }
    public override string ToString()
    {
        return string.Format("[{0}-{1}]", x.ToString(), y.ToString());
    }
}
public class Test
{
    static void Main()
    {
        Location l = new Location();
        l.x = l.y = 6;
        Console.WriteLine(l);//[6-6]
        l.Change(5, 5);
        Console.WriteLine(l);//[5-5]
        object o = l;
        Console.WriteLine(o);//[5-5]
 
        //o Change      ,      Location
        ////   Location,        ,     
        //          
        ((Location)o).Change(9, 9);
        //[5-5]
        Console.WriteLine(o);
    }
}

上記のコードは箱詰めの値タイプのフィールドを変更することはできません.私たちはインタフェースでC#をだまして値タイプのフィールドを変更することができます[Location:IChangeBoxedLocation]:
 1 public interface IChangeBoxedLocation
 2 {
 3     void Change(int x, int y);
 4 }
 5 public class Test
 6 {
 7     static void Main()
 8     {
 9         Location l = new Location();
10         l.x = l.y = 6;
11         object o = l;
12         //        ,        ,      
13         ((IChangeBoxedLocation)l).Change(5, 5);
14         Console.WriteLine(l);//[6-6]
15  
16         //  o       ,    Change      o    
17         ((IChangeBoxedLocation)o).Change(9, 9);
18         Console.WriteLine(o);//[9-9]
19     }
20 }

私の通俗的な理解は:私は1人の[値のタイプLocation]で、私はプログラミングの能力があって[IChangeBoxedLocationインタフェースを実現する]ので、必要な時にあなたは私をプログラマーとして使うことができます.
同じ方法のインタフェースを複数実装
 1 public interface IWindow
 2 {
 3     void Print();
 4 }
 5  
 6 public interface IConsole
 7 {
 8     void Print();
 9 }
10  
11 public class MyClass : IWindow, IConsole
12 {
13     void IWindow.Print()
14     {
15         //....
16     }
17     void IConsole.Print()
18     {
19         //....
20     }
21     public void Print()
22     {
23         //....
24     }
25 }

MyClassはPrintメソッドを多く実装しているので、C#コンパイラにどのPrintがどのインタフェースを実装したかを教え、C#ではメソッド名の前にインタフェース名を付けることでC#コンパイラに伝えます.public void Print()は一般的な方法であり、インタフェースとは何の関係もない[void IWindow.Print()を削除すると、この方法[public void Print()]はIWindowインタフェースを実現する方法であり、C#コンパイラはインタフェースメンバーを判別する際に、インタフェースメンバーを完全に限定してからメンバーを完全に限定しない順序で判別する].
上記の2つの完全限定インタフェースメソッドはpublicとして宣言されていない.これは、これらのメソッドには二重のアイデンティティがあり、[タイプがインタフェースタイプに変換された場合:MyClassがIWindowまたはIConsoleに変換された場合]、プライベート[MyClassインスタンスの場合]があるからである.1つのタイプで完全限定名でインタフェースメソッドを定義する場合、このメソッドはプライベートとみなされます.タイプ自体が呼び出すことができないため、1つのインタフェースに変換すると、このメソッドが呼び出されます.この場合、また共有メソッドです.
インタフェースメンバー実装の表示
インプリメンテーションインタフェースのメンバーが、上記の完全限定名を使用してインタフェースを実装していることを示します.実装インタフェースメンバーがアプリケーションにより多くのタイプのセキュリティを提供していることを示します.