How to encapsulate a property in a base class?
c#, object-oriented-analysis, oop, uml
Solution
Maybe you're looking for something like this? Note, I left some things out because they weren't important to the generic solution part of the problem (like QuestionText). I also left out the base class because it appeared to be nothing more than a pass-through, and an extra, unnecessary layer. This may not be exactly what you're looking for, but I hope it helps get you there.
First, this is how everything is used: Edit: Notice how they can all be treated as the non-generic IProblem now.
private static void StackOverflowQuestion()
{
IProblem<int> problem1 = new IntProblem(2, 4);
problem1.Response = 6;
IProblem<decimal> problem2 = new DecimalProblem(5, 10);
problem2.Response = .5M;
Console.WriteLine("Problem 1 is correct: {0}", problem1.IsCorrect());
Console.WriteLine("Problem 2 is correct: {0}", problem2.IsCorrect());
List<IProblem> problems = new List<IProblem>();
problems.Add(problem1);
problems.Add(problem2);
problems.ForEach(problem => Debug.WriteLine(problem.GetResponse()));
}
Edit: Here's the non-generic interface so many problems can be used in a list and treated the same way:
public interface IProblem
{
object GetResponse();
}
Here's the interface: Edit: Notice that this now implements the non-generic interface.
public interface IProblem<T> : IProblem
{
T Response { get; set; }
bool IsCorrect();
}
And here are the classes: Edit: Notice the new GetResponse() methods.
public class IntProblem : IProblem<int>
{
private int _number1 { get; set; }
private int _number2 { get; set; }
public int Response { get; set; }
public IntProblem(int number1, int number2)
{
this._number1 = number1;
this._number2 = number2;
}
public bool IsCorrect()
{
return this._number1 + this._number2 == Response;
}
public object GetResponse()
{
return this.Response;
}
}
public class DecimalProblem : IProblem<decimal>
{
private decimal _number1 { get; set; }
private decimal _number2 { get; set; }
public decimal Response { get; set; }
public DecimalProblem(decimal number1, decimal number2)
{
this._number1 = number1;
this._number2 = number2;
}
public bool IsCorrect()
{
return this._number1 / this._number2 == Response;
}
public object GetResponse()
{
return this.Response;
}
}
Problem
My scenario is about developing Math Problems. As a `IProblem` interface, I thought that the two main properties that it should contain are `QuestionText` and `Response`. `QuestionText` always will be a string, but `Response` sometimes can be a complex object (a custom `Fraction` struc) or another datatype like string, decimal, int, etc. ``` public interface IProblem { string QuestionText { get; set; } object Response { get; } bool IsComplete(); bool IsCorrect(); } ``` As you can see, `Response` is object. I guessed this datatype because all problems by nature have a response. And as it's an object, I define only get for future errors (casting problems). My idea is later, in a concrete class to access to this property (`Response`), without the necessity to cast. Check it out? ``` public abstract class Problem : IProblem { public string QuestionText { get; set;} public object Response { get; protected set; } public virtual bool IsComplete() { return true; } public abstract bool IsCorrect(); } public class BinaryProblem : Problem { public decimal N1 { get; set; } public decimal N2 { get; set; } public decimal Response { get { return (decimal)base.Response; } set { base.Response = value; } } public override bool IsCorrect() { return N1 + N2 == Response; } } ``` And here I'm testing the value. ``` static void Main(string[] args) { BinaryProblem p = new BinaryProblem(); p.N1 = 2; p.N2 = 4; p.Response = 6; IProblem p2 = p; Console.WriteLine(p2.Response); Console.WriteLine(p2.IsComplete().ToString()); } ``` Until now, it works, but I want to know if what I'm doing is correct or a good practice. I've seen another people use `new` operator to do this. Others don't use the word `base`. Is this a good way? Can it be causing future errors? Please, give me a feedback about my design. EDIT: It's really necessary to access to the Response in a non-generic interface.