11

次のC#インターフェイスを定義します。

public interface IShape
{
    int NumberOfLineSegments {get;}
    int Area {get;}
}

次に、台形、正方形など、いくつかの長方形のクラスを定義します。これらのクラスはすべてArea()プロパティが異なりますが、NumberOfLineSegments()は常に4を返します。したがって、Rectangle(またはIRectangle)と呼ばれる「interim」クラスまたはインターフェイスが必要です。

public Rectangle : IShape
{
    public int NumberOfLineSegments{get{return 4;}}
}

RectangleにNumberOfLineSegment()のみを実装し、それを派生クラスに任せて残りを実装するようにします。

public Square : Rectangle 
{
    public int Area() {get{return length*height;}
}

ただし、IShapeはインターフェイスであるため、RectangleクラスはArea()も実装する必要がありますが、これは実装方法がわかりません。したがって、Rectangleの「ダミー」Area()メソッドを定義するかどうかにかかわらず、行き詰まっているようです。継承を使用します。

これを回避する方法はありますか?私はc#を介してRichterのclrを、そしてStackOverflowで広範囲に読んだことがあります。前もって感謝します!

4

6 に答える 6

7

Rectangleクラスはである必要があり、メソッドを抽象としてabstract 定義します。Area()

public interface IShape
{
    int NumberOfLineSegments {get;}
    float Area{get;}
}

public abstract class RectangleBase : IShape
{
    public int NumberOfLineSegments { get { return 4; } }

    public abstract float Area { get; }
}

public sealed class Square : RectangleBase
{
    public override fload Area() { get { return length*height; }
}

また、Rectangleインスタンスが必要な場合:

public sealed class Rectangle : ReectangleBase
{
    public int NumberOfLineSegments { get { return 4; } }

    public float Area { get { throw new NotImplementedException(); } }
}
于 2012-07-17T13:41:29.517 に答える
5

2つのオプションがあります。

  1. 実装を仮想で空にする(またはをスローするNotImplementedException)ので、派生するま​​でデフォルトでは何も実行されません。
  2. 基本クラスを抽象化し、チェーンに強制するインターフェイスメソッドの抽象シグネチャを作成します。

番号2は、派生クラスにメソッドの実装を強制するため、はるかに望ましいですが、番号1では、派生クラスは基本仮想メソッドをオーバーライドするように強制されません。

コンパイラは抽象クラス自体をインスタンス化できないことを認識し、派生クラスには抽象メソッドを実装するように強制されるため、抽象メソッドはインターフェイス定義を正常に満たすことができます。

とは言うものの、特定のタイプに意味をなさないインターフェースメンバーがある場合、それは通常、インターフェースを分類するためのインジケーターです。

public interface IShape : ICalculateArea, IHaveLineSegments
{
}

public interface ICalculateArea
{
    float Area { get; }
}

public interface IHaveLineSegments
{
    int NumberOfLineSegments { get; }
}

class Rectangle : IHaveLineSegments
{
    public int NumberOfLineSegments { get; private set; }
}

class Square : Rectangle, IShape
{
    public float Area { get; private set; }
}
于 2012-07-17T13:42:23.883 に答える
1

メソッドを抽象として定義します。

public abstract float Area{get;}
于 2012-07-17T13:41:41.287 に答える
1

インターフェイスを実装する抽象クラスを使用します。

public abstract class Rectangle : IShape {
    public int NumberOfLineSegments { get { return 4; } }
    public abstract float Area { get; }
}

特定のrectangleクラスは、Rectangle抽象クラスから単純に継承します。

于 2012-07-17T13:41:54.643 に答える
0

これで大丈夫ですか?派生クラスでの実装を強制します。

public abstract class Rectangle : IShape
{
    NumberOfLineSegments{get{return 4;}}
    abstract float Area { get; }
}
于 2012-07-17T13:42:09.400 に答える
0

個人的には@sllのソリューション(および本質的に同じ他のソリューション)が好きですが、記録のためにもう1つの方法があります:

public interface IShape
{
    int NumberOfLineSegments {get;}
    float Area{get;}
}

public class Rectangle
{
    public int NumberOfLineSegments { get { return 4; } }
}

public sealed class Square : Rectangle, IShape
{
    public float Area() { get { return length*height; }
}

このようabstractにして、厳密なスーパークラスを定義するコストをかけてクラスを節約できます(したがって、に対して異なるスーパークラスを持つことはできませんSquare)。

Rectangleを実装していないにもかかわらず、これは機能することに注意してくださいIShape

于 2012-07-17T13:46:25.147 に答える