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

时间:2012-07-17 13:39:01

标签: c# class inheritance interface

定义以下C#接口:

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

接下来,我想定义几个矩形类:Trapezoid,square等。所有这些类的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中广泛阅读。提前谢谢!

6 个答案:

答案 0 :(得分: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(); } }
}

答案 1 :(得分:5)

有两种选择。

  1. 使实现成为虚拟和空(或抛出NotImplementedException),因此在派生之前它默认不执行任何操作。
  2. 使基类抽象化,并为要强制链接的接口方法创建抽象签名。
  3. 数字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; }
    }
    

答案 2 :(得分:1)

将方法定义为抽象。

public abstract float Area{get;}

答案 3 :(得分:1)

使用实现接口的抽象类:

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

然后,您的特定矩形类只是从Rectangle抽象类继承。

答案 4 :(得分:0)

这没关系?强制派生类中的实现。

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

答案 5 :(得分: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,但仍然有效。