Considering the rules of good OOP and design, is it correct to write a method in an interface which has as input types or output types classes which implements the interface?
I give you an example of a very simple exercise I must do, regarding complex numbers:
public interface IComplex
{
double GetImaginary();
double GetReal();
ComplexImpl Conjugate();
ComplexImpl Add(ComplexImpl y);
}
/*----------------------------------------------------*/
public class ComplexImpl : IComplex
{
private double real;
private double imaginary;
public ComplexImpl(double real, double imaginary) { this.real = real; this.imaginary = imaginary; }
public double GetReal() { return this.real; }
public double GetImaginary() { return this.imaginary; }
public ComplexImpl Conjugate()
{
ComplexImpl conjugate = new ComplexImpl(this.real, -this.imaginary);
return conjugate;
}
public ComplexImpl Add(ComplexImpl y)
{
ComplexImpl result = new ComplexImpl(this.real y.real, this.imaginary y.imaginary);
return result;
}
}
Considering the interface IComplex: is it correct to write the methods Conjugate and Add such that they have as input (and/or output) objects which are instantiations of the class ComplexImpl?
Consider that the class ComplexImpl implements the interface when this methods are defined.
EDIT:
For those of you who answer: first of all thank you, however I have the following problem. If I substitute "ComplexImpl" with "IComplex" both in the interface and in the class, I obtain this error in the method Add:
"'IComplex' does not contain a definition for 'imaginary' and no accessible extension method 'imaginary' accepting a first argument of type 'IComplex' could be found".
The only way to solve this is through the use of Generics?
CodePudding user response:
I suggest you use the interface IComplex instead of ComplexImpl in the interface. This will still yield the desired results without relying on an implementation of the interface.
public interface IComplex
{
double GetImaginary();
double GetReal();
IComplex Conjugate();
IComplex Add(IComplex y);
}
CodePudding user response:
This thing is breaking the reason to use interfaces: To abstract implemntations. An easy and bearable fix to this would be:
public interface IComplex
{
double GetImaginary();
double GetReal();
IComplex Conjugate();
IComplex Add(IComplex y);
}
This way an implmentation is returned, but the interface stays clean and has no knowledge about an implementation.
CodePudding user response:
You can make the interface or methods generic, constrained over your interface.
Choice 1
public interface IComplex<TComplex>
where TComplex : IComplex
{
double GetImaginary();
double GetReal();
TComplex Conjugate();
TComplex Add(TComplex y);
}
Choice 2
public interface IComplex
{
double GetImaginary();
double GetReal();
TComplex Conjugate<TComplex>() where TComplex : IComplex;
TComplext Add<TComplex>(TComplex y) where TComplex : IComplex;
}