Let’s suppose that we have 3 classes: Base, Root and Child.
public abstract class Base
{
protected int _Value;
public double DoSomeWork(int value)
{
_Value = value;
double result = Calculate();
return result;
}
public abstract double Calculate();
public Child CreateChild(int length)
{
return new Child(this);
}
}
public class Root : Base
{
public override double Calculate()
{
return _Value;
}
}
public class Child : Base
{
readonly Base _Container;
public Child(Base container)
{
_Container = container;
}
public override double Calculate()
{
double result = _Container.Calculate();
// do some more calculation
return result;
}
}
My issue here is that I would like only the DoSomeWork (and CreateChild) be publicly accessible, but in my “architecture” I am forced to make Calculate public also. Or am I?
Any input will be very much appreciated.
Edit:
Calculate cannot be protected because of this line in Child
double result = _Container.Calculate();
which would cause a build error to occur.
No, you can make it
protected. That way your derived class will still have access to it and be able to override it, but it won’t be allowed publicly.Good thinking, this is exactly the way to do it: override as little as possible and hide as much as possible.
– Edit –
Since this is probably a simplified example of what you are actually doing, I can only provide a guess to what these methods do, but here it goes.
I have a feeling that
Calculatemethod might not belong to yourBaseclass. It looks like it provides an auxiliary calculation result used byDoSomeWork. Inheritance is usually used when your base class has some common calculation to “offer” to derived classes, so that you don’t have to repeat yourself.For example, let’s say that your
DoSomeWorkmethod has some certain functionality that doesn’t change, but requires an “external” calculation to be performed first. If you started by creating a simple separate interface for the external calculation:You could define different implementations of this interface. You can start by creating a simple implementation (similar to your
Rootfunctionality):And you could also easily wrap existing implementations inside more complex classes (similar to what
CreateChildintends to do):And then, your actual class needs to use this functionality to some intended “extra work”:
Or, you could pass the “calculator” to
DoSomeWorkon each call, as a parameter, and change the complex class to something like: