Define the following C# interface:
public interface IShape
{
int NumberOfLineSegments {get;}
int Area {get;}
}
Next, I want to define several rectangle classes: Trapezoid, square,etc. All of these classes differ in their Area() property, but NumberOfLineSegments() always returns 4. Therefore, I would like an 'interim' class or interface, called Rectangle (or IRectangle), that looks something like:
public Rectangle : IShape
{
public int NumberOfLineSegments{get{return 4;}}
}
I want Rectangle to implement only NumberOfLineSegment(), and leave it to its derived classes to implement the rest:
public Square : Rectangle
{
public int Area() {get{return length*height;}
}
However, since IShape is an interface, the Rectangle class must implement also Area(), which it knows not how to implement.. Thus I seem to be stuck, either with defining a 'dummy' Area() method for Rectangle, or not using inheritence at all.
Is there a way to circumvent this? I have read extensively through Richter's clr via c#, and in StackOverflow. Thanks in advance!
The derived interface inherits the members from its base interfaces. A class that implements a derived interface must implement all members in the derived interface, including all members of the derived interface's base interfaces.
Interface inheritance and interface implementation are not the same thing. A class implements an interface by declaring that it implements an interface and then containing the required members to to implement that interface. Interface inheritance refers to an interface inheriting from one or more other interfaces.
Yes, it is mandatory to implement all the methods in a class that implements an interface until and unless that class is declared as an abstract class.
An interface is not a class. It contains only method signatures. It has no implementation on its own and cannot be instantiated. Its implementation logic is provided by the classes that derived from it.
Rectangle
class should be abstract
and define Area()
method as abstract.
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; }
}
And if you need Rectangle instances:
public sealed class Rectangle : ReectangleBase
{
public int NumberOfLineSegments { get { return 4; } }
public float Area { get { throw new NotImplementedException(); } }
}
There are two options.
NotImplementedException
), so it does nothing by default until derived.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; }
}
define the method as abstract.
public abstract float Area{get;}
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With