定义以下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中广泛阅读。提前谢谢!
答案 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)
有两种选择。
NotImplementedException
),因此在派生之前它默认不执行任何操作。数字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
,但仍然有效。