11

定义以下 C# 接口:

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

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

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# 和 StackOverflow 广泛阅读了 Richter 的 clr。提前致谢!

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

There are two options.

  1. Make the implementation virtual and empty (or throw a NotImplementedException), so it does nothing by default until derived.
  2. Make the base class abstract and create abstract signatures for the interface methods you want to force down the chain.

Number 2 is much more preferable, as it forces derived classes to implement the method, whereas in number 1 derived classes are not forced to override base virtual methods.

Abstract methods can successfully satisfy interface definitions as the compiler will know that abstract classes themselves cannot be instantiated, and any derived classes are forced to have the abstract method implemented.

That said, if there are interface members that do not make sense to a particular type, it is usually an indicator to break down your interfaces:

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

define the method as abstract.

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

Use an abstract class which implements the interface:

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

Your particular rectangle classes then simply inherit from the Rectangle abstract class.

于 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 的解决方案(以及其他基本相同的解决方案),但为了记录,还有另一种方法:

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 回答