よく使う。
成果物
継承
interface IControl { void Paint(); } class Control : IControl { public void Paint() { Console.WriteLine($"{this.GetType().Name}.Paint"); } }
Control
クラスはIControl
インタフェースを継承している。
多重継承
interface IControl { void Paint(); } interface IDataBound { void Bind(Binder b); } public class EditBox: IControl, IDataBound { public void Paint() { } public void Bind(Binder b) { } }
EditBox
クラスはIControl
とIDataBound
のインタフェースを継承している。
暗黙的変換
EditBox editBox = new EditBox();
EditBox
クラスはIControl
とIDataBound
のインタフェースを継承しているため、それぞれのインタフェース型に変換できる。暗黙的キャスト。
IControl control = editBox; IDataBound dataBound = editBox;
明示的にキャストするなら以下。
object obj = new EditBox(); IControl control = (IControl)obj; IDataBound dataBound = (IDataBound)obj;
明示的なインタフェースメンバの実装
public class EditBox: IControl, IDataBound { void IControl.Paint() { } void IDataBound.Bind(Binder b) { } }
各インタフェースのメソッドに、各インタフェース名を付与して実装する。こうすることで、インタフェース型を介してのみアクセス可能になる。
EditBox editBox = new EditBox(); editBox.Paint(); // Error, no such method IControl control = editBox; control.Paint(); // Ok
所感
明示的なインタフェースメンバの実装について、その使いどころがよくわからない。
上記の例だと、EditBox
型としてはPaint
を使えないようにしつつ、IControl
型としてはPaint
を使えるようにしている。
別インタフェース同士でシグネチャが一致したときには明示実装するしかなさそうだが。他に意図してこれを使う場面が思いつかない。つまり「シグネチャが重複してしまったときの実装方法」ということか?
対象環境
- Raspbierry pi 3 Model B+
- Raspbian stretch 9.0 2018-11-13 ※
- bash 4.4.12(1)-release ※
- SQLite 3.29.0 ※
- C# dotnet 3.0.100 ※
$ uname -a Linux raspberrypi 4.19.42-v7+ #1218 SMP Tue May 14 00:48:17 BST 2019 armv7l GNU/Linux