In C++, you can do the following:
class base_class
{
public:
virtual void do_something() = 0;
};
class derived_class : public base_class
{
private:
virtual void do_something()
{
std::cout << "do_something() called";
}
};
The derived_class
overrides the method do_something()
and makes it private
. The effect is, that the only way to call this method is like this:
base_class *object = new derived_class();
object->do_something();
If you declare the object as of type derived_class
, you can't call the method because it's private:
derived_class *object = new derived_class();
object->do_something();
// --> error C2248: '::derived_class::do_something' : cannot access private member declared in class '::derived_class'
I think this is quite nice, because if you create an abstract class that is used as an interface, you can make sure that nobody accidentally declares a field as the concrete type, but always uses the interface class.
Since in C# / .NET in general, you aren't allowed to narrow the access from public
to private
when overriding a method, is there a way to achieve a similar effect here?
The problem with this strategy, should it be implemented, is that the method is not truly private. If you were to upcast a reference to
base_class
, then the method is now public. Since it's a virtual method, user code will executederived_class::do_something()
eventhough it's marked as private.If you explicitly implement an interface, this will at least encourage people to use the interface type in the declaration.
One will only see MyMethod after casting the instance to
IMyInterface
. If the declaration uses the interface type, there is no casting needed in subsequent uses.MSDN page on explicit interface implementation (thanks Luke, saves me a few seconds^^)
You are able to decrease a method's availability by marking it as
new
.The example from MSDN's CA2222: Do not decrease inherited member visibility:
This is really more interesting as an academic exercise; if your code is truly dependent on not being able to call
BasePublicMethod
onADerivedType
, that's a warning sign of a dubious design.You can do this in the .Net world too, using explicit interface implementation
As an example,
BindingList<T>
implementsIBindingList
, but you have to cast it toIBindingList
to see the method.