This isn’t really related to anything I am working on currently, its more of a question I really couldn’t find an answer for.
Class modifiers like MustInherit
or NotOverridable
to me, seem like they only need to be used in larger programs that have multiple people working on and editing it.
I can see in a situation like that how forcing or preventing people to inherit or override makes sense, but in smaller programs I just don’t see why or if these would be used.
Is that basically what these modifiers are for or am I missing the purpose of them.
1
I can see in a situation like that how forcing or preventing people to inherit or override makes sense, but in smaller programs I just don’t see why or if these would be used.
This (“Oh, it’s just a small program that I alone am working on, and I know what I’m doing.”) is a fallacy.
There has been quite a bit of research done which has found that people can only keep a certain amount of things in mind at a time. By forcing yourself to remember if that function is overridable or not, that’s one less thing you can spend on something useful, like the problem at hand. And even if you do remember it (the program is small, after all), then you’re spending energy on keeping it in mind – meaning you spend less time programming or are more tired after you’re done.
And let’s face facts, people don’t remember things better as they progress through adulthood. Even if you can remember all of the details of this program today, what about a year from now? 5 years from now? It’s good to get into the habit now.
And that ignores the fact that you’re human (I presume). People make errors. By marking something as abstract or sealed, you let the computer act as a safety net so you don’t go off and extend your class design in terrible ways simply because you mistakenly thought you could/should.
1
Quick Answer
Members inheritance modifiers allows developers to put guidelines, on how an object members should be inherited.
Long, Boring, Extended Answer
The combination of non-virtual methods and virtual methods, (and “final” or “sealed”, and “abstract” methods), in an algorithm, allows to restrict a goal.
Remember that those modifiers may vary from one Programming Language to Another P.L.
MustInherit
from V.B. is commonly used asvirtual
, in other P.L.Overriden
from V.B. is commonly used asoverride
, in other P.L.NotOverridable
from V.B. is not explicitly used in many P.L., I usually add a small, one line comment like/* nonvirtual */
.
In Java, before the @override
marker or directive was added, I used /* @override */
.
I develop a lot of large O.O. programs, usually done entirely by myself, most of them for work, sometimes as a hobby. Even, in small programs, I add modifiers, because the logic of trhe program requires.
A good example, is when you combine several of them:
public class EntityClass
{
public virtual bool IsReady()
{
bool Result = false;
// depends on the class
return Result;
} // bool IsReady()
public virtual bool GenerateKey()
{
bool Result = false;
// depends on the class
return Result;
} // bool GenerateKey()
public virtual bool BeforeInsert()
{
bool Result = false;
// depends on the class
return Result;
} // bool BeforeInsert()
public virtual bool ConfirmedInsert()
{
bool Result = false;
// depends on the class
return Result;
} // bool ConfirmedInsert()
public virtual bool AfterInsert()
{
bool Result = false;
// depends on the class
return Result;
} // bool AfterInsert()
public /* nonvirtual */ bool InsertAndGenerateKey()
{
bool Result = false;
if (this.IsReady())
{
Result = GenerateKey();
if (Result)
{
Result = BeforeInsert();
if (Result)
{
Result = ConfirmedInsert();
if (Result)
{
AfterInsert();
}
}
}
} // if (this.IsReady())
return Result;
} // bool InsertAndGenerateKey
public /* nonvirtual */ bool InsertAndIgnoreKey()
{
bool Result = false;
if (this.IsReady())
{
Result = BeforeInsert();
if (Result)
{
Result = ConfirmedInsert();
if (Result)
{
AfterInsert();
}
}
} // if (this.IsReady())
return Result;
} // bool InsertAndIgnoreKey(...)
public /* nonvirtual */ bool InsertWithAssignedKey()
{
bool Result = false;
if (this.IsReady())
{
Result = BeforeInsert();
if (Result)
{
Result = ConfirmedInsert();
if (Result)
{
AfterInsert();
}
}
} // if (this.IsReady())
return Result;
} // bool InsertWithAssignedKey(...)
} // class EntityClass
In this C# example, there are several methods, part of a single class.
Check that the combined non virtual methods, usually call other virtual methods.
This combination, restricted by the modifiers, defines a process,
called “Strategy Design Pattern”, that has a goal, but, yet, allows,
some customization by subclassing.
2