13,009
回編集
(→概要) |
|||
308行目: | 308行目: | ||
} | } | ||
</syntaxhighlight> | </syntaxhighlight> | ||
<br><br> | |||
== 複数のインターフェイスの実装(多重継承) == | |||
C#は、クラスの多重継承ができないが、インターフェイスの複数の実装ができる。<br> | |||
<syntaxhighlight lang="c#"> | |||
struct Id : IComparable<Id>, IEquatable<Id> | |||
{ | |||
public int Value { get; set; } | |||
public int CompareTo(Id other) => Value.CompareTo(other.Value); | |||
public bool Equals(Id other) => Value == other.Value; | |||
} | |||
</syntaxhighlight> | |||
<br><br> | |||
== 型・引数が異なるジェネリックインターフェイス == | |||
C#では、オーバーロードが可能な限り、同名のメンバを持つ複数のインターフェイスを実装することができる。<br> | |||
(オーバーロードできない場合は、次のセクション"明示的実装"が必要になる)<br> | |||
<br> | <br> | ||
これは、ジェネリックインターフェイスにおいて、型・引数が異なる場合、複数実装する時に効果がある。<br> | |||
<br> | |||
例えば、標準ライブラリのIEquatable<T>インターフェイス(System名前空間)について、異なる型・引数で複数実装できる。<br> | |||
AとBの2つのクラスがある時、IEquatable<A>とIEquatable<B>という2つの実装を持つことができる。<br> | |||
<br> | |||
具体的な用途として、以下のような場面で有効である。<br> | |||
* 図形全般を表すShapeクラスがある。 | |||
* Shapeクラスから派生した矩形型Rectangleクラスがある。<br>Rectangleクラスは、縦横の両方の比較で等値判定する。 | |||
* Shapeクラスから派生した円型Circleクラスがある。<br>Circleクラスは、半径の比較で等値判定する。 | |||
* Shapeクラスは、矩形同士、円同士でのみ等値判定する。型が異なる場合は、その時点で不一致となる。 | |||
<br> | |||
この条件下において、各クラスに以下のようなインターフェイスを持つことができる。<br> | |||
* Shapeクラスは他のShapeクラスと比較できるので、IEquatable<Shape>を実装できる。 | |||
* Rectangleクラスは他のRectangleクラスと比較できるので、IEquatable<Rectangle>を実装できる。<br>RectangleクラスはShapeクラスから派生しているため、IEquatable<Shape>でもある。 | |||
* Circleクラスは他のCircleクラスと比較できるので、IEquatable<Circle>を実装できる。<br>CircleクラスはShapeクラスから派生しているので、IEquatable<Shape>でもある。 | |||
<br> | |||
以下の例では、上記のような用途を実装している。<br> | |||
<syntaxhighlight lang="c#"> | |||
using System; | |||
abstract class Shape : IEquatable<Shape> | |||
{ | |||
public abstract bool Equals(Shape other); | |||
} | |||
class Rectangle : Shape, IEquatable<Rectangle> | |||
{ | |||
public double Width { get; set; } | |||
public double Height { get; set; } | |||
public override bool Equals(Shape other) => Equals(other as Rectangle); | |||
public bool Equals(Rectangle other) => other != null && Width == other.Width && Height == other.Height; | |||
} | |||
class Circle : Shape, IEquatable<Circle> | |||
{ | |||
public double Radius { get; set; } | |||
public override bool Equals(Shape other) => Equals(other as Circle); | |||
public bool Equals(Circle other) => other != null && Radius == other.Radius; | |||
} | |||
</syntaxhighlight> | |||
<br><br> | |||
__FORCETOC__ | __FORCETOC__ | ||
[[カテゴリ:C_Sharp]] | [[カテゴリ:C_Sharp]] |