继承一个接口,实现部分方法,让派生类实现其余的

zuu*_*uuz 11 c# inheritance interface class

定义以下C#接口:

public interface IShape
{
    int NumberOfLineSegments {get;}
    int Area {get;}
}
Run Code Online (Sandbox Code Playgroud)

接下来,我想定义几个矩形类:Trapezoid,square等.所有这些类的Area()属性都不同,但NumberOfLineSegments()总是返回4.因此,我想要一个名为Rectangle(或IRectangle)的'临时'类或接口,它看起来像:

public Rectangle : IShape
{
    public int NumberOfLineSegments{get{return 4;}}
}
Run Code Online (Sandbox Code Playgroud)

我希望Rectangle只实现NumberOfLineSegment(),并将其留给派生类来实现其余的:

public Square : Rectangle 
{
    public int Area() {get{return length*height;}
}
Run Code Online (Sandbox Code Playgroud)

但是,由于IShape是一个接口,Rectangle类也必须实现Area(),它不知道如何实现.因此,我似乎被卡住了,要么为Rectangle定义'dummy'Fare()方法,要么完全使用继承权.

有没有办法规避这个?我通过c#和StackOverflow在Richter的clr中广泛阅读.提前致谢!

sll*_*sll 7

Rectangleclass应该是abstractArea()方法定义为抽象.

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; }
}
Run Code Online (Sandbox Code Playgroud)

如果你需要Rectangle实例:

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

    public float Area { get { throw new NotImplementedException(); } }
}
Run Code Online (Sandbox Code Playgroud)


Ada*_*rth 5

有两种选择.

  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; }
}
Run Code Online (Sandbox Code Playgroud)