インターフェースとは、関連する機能をひとまとめにしたメンバーを持つ型です。クラスの利用側を実装から切り離すことで、複数の異なる実装を可能にしたり、書式設定、比較、変換といった汎用的な振る舞いに対応したりできます。
インターフェースの構文はクラスや構造体とよく似ていますが、メソッドとプロパティはシグネチャだけを書き、本体は持ちません。
public interface ILanguage
{
string LanguageName { get; set; }
string Speak();
}
public class ItalianTaveller : ILanguage, ICloneable
{
public string LanguageName { get; set; } = "Italiano";
public string Speak()
{
return "Ciao mondo";
}
public object Clone()
{
ItalianTaveller it = new ItalianTaveller();
it.LanguageName = this.LanguageName;
return it;
}
}
インターフェースで定義されたすべての操作を実装する必要があります。
インターフェースには、ほかのメンバーに加えて、インスタンスメソッドやプロパティを含めることができます。
あるオブジェクトを別のオブジェクトと比較できるようにするには、そのオブジェクトがIComparable<T>インターフェースを実装している必要があります。このインターフェースには、実装が必要なメソッドが1つだけあります。それがint CompareTo(T other)です。
CompareToメソッドの戻り値は、次の3つのいずれかです。
この演習では、ラジコンカーの作業をもう少し進めます。
実験用の車が開発されたため、テストコースを生産モデルと実験モデルの両方に対応させなければならなくなりました。2種類の車はすでに作られているので、テストコースで両方を扱う方法を考える必要があります。
さらに、生産モデルの車も少しずつ成果を上げ始めています。チームのボスは、生産モデルの車のランキングを公開して、競争心を保ちたいと考えています。
2種類の車のDrive()の実装を公開するメソッドを、IRemoteControlCarインターフェースに追加してください。
TestTrack.Race(new ProductionRemoteControlCar());
TestTrack.Race(new ExperimentalRemoteControlCar());
// this should execute without an exception being thrown
2種類の車のDistanceTravelledプロパティの実装を公開するプロパティを、IRemoteControlCarインターフェースに追加してください。
var prod = new ProductionRemoteControlCar();
TestTrack.Race(prod);
var exp = new ExperimentalRemoteControlCar();
TestTrack.Race(exp);
prod.DistanceTravelled
// => 10
exp.DistanceTravelled
// => 20
ProductionRemoteControlCarクラスにIComparable<T>インターフェースを実装してください。車のデフォルトの並べ替え順は、勝利数の昇順とします。
静的メソッドTestTrack.GetRankedCars()を実装し、渡された車を勝利数の昇順に並べ替えて返すようにしてください。
var prc1 = new ProductionRemoteControlCar();
var prc2 = new ProductionRemoteControlCar();
prc1.NumberOfVictories = 3;
prc2.NumberOfVictories = 2;
var rankings = TestTrack.GetRankedCars(prc1, prc2);
// => rankings[1] == prc1