4

I'm wondering if there is a widely accepted convention for naming base classed in OOP. Does marking a parent class with "Base" indicate that it's abstract or that it's just an extended class? Or in other words, is it better to mark abstract class with the word "base" or classes that have multiple extensions?

For example, let's say we have a vehicle class which is extended by car and bicycle classes, each of which further extended. If we call the car class BaseCar, without looking at its definition, is it inferred that it's an abstract class, or a class that is extended? Would it be surprising if there are instantiations of BaseCar itself?

3
  • 4
    A class named Base anything is more an indication of a bad name than anything else. You do not need "base" or "abstract" in the name to have an abstraction. You just need an idea brought to fruition with code that sits behind a name that explains the abstraction and why you would use it without seeing the code that sits behind the name. Mar 4 at 1:04
  • 2
    BaseStar, BaseBuilder, Base, BaseBall. In their own contexts are valid objects.
    – Kain0_0
    Mar 4 at 4:38
  • It wouldn't matter but the class names should make sense. The class represents a Car should be called Car no matter if it is an abstract class, base class or whatever. The convention could be harmful in because you might have BaseCar, Car, DerivedCar classes that all represent one thing leading to confusing class heirachies. Mar 30 at 8:59
5

"I'm wondering if there is a widely accepted convention for naming base classed in OOP"

Short answer: no, there is not.

If you want to read something directly out of the name of a class, you need to consult the programming guidelines of your team or organization. There are only very few widely accepted naming conventions, and even those don't apply to "OOP in general", but usually to a specific language ecosystem.

For example, in C#, I would usually expect a type name starting with a single I to be an interface (though not every team names gives interfaces always an I prefix; it is a convention suggested by Microsoft). For a class ending with the word Exception I would expect it to be a derivation of System.Exception. And (as mentioned in a comment by @Blake, thanks), attribute classes in C# usually end with the suffix Attribute. In Python, the PEP 8 style guide suggests to let exception classes (which represent errors) end with the name Error.

Specifically for C#, I guess that list is complete. I cannot remember to have seen a naming style "broadly accepted" across teams and organizations, where part of a class name induces a clear semantics.

5
  • Funny you mention C#, as I was implementing in C# when I thought of the question. And I've also found the only 2 common conventions of C# to be I for interfaces and Exception extension on built in Exception.
    – alamoot
    Mar 4 at 5:43
  • The I prefix is a C# thing not a Java thing. Java is perfectly happy to respect client codes right to not know if it's talking to an interface or a concrete type. Now if only Java respected that in its binaries so you wouldn't have to recompile the client when you switch from concrete to interface. We probably wouldn't have so many premature interfaces. Mar 4 at 7:42
  • @candied_orange: ok, I removed the Java part from my answer, it may not be so common there as I thought.
    – Doc Brown
    Mar 4 at 8:07
  • 1
    Thank you. I've only ever seen the I prefix in Java when C# programmers are working in Java and haven't had their first code review in Java. Mar 4 at 8:09
  • 1
    One more for C# is Attribute classes always end with Attribute.
    – Blake
    Mar 4 at 13:47
2

Honestly this reeks of Hungarian Notation. Or to be more correct about it badly applied Hungarian Notation.

Hungarian Notation was meant to express type information that the programming language could not. For example in Assembly it is helpful to know if you are dealing with a pointer to a string, or an int. The language isn't going to track this for you so a local naming standard encoding the type information is particularly helpful.

However this falls flat on its face in languages which have expressive type systems that can encode this information outside of the name. This could by by designating the type as abstract for example or only providing protected constructors only available to deriving types.

A good example of poorly applied Hungarian Notation is the I in a C# interface name like IComparable. Comparable is a sufficiently good name, and the fact that its an interface is surfaced easily enough by looking at its definition, or through an ide.

So i'd ask. Does this language allow me to express in the type system that this class is available for derivation? If so then drop the Base and just call it Car. It easy enough to identify that Model-Y derives from Car.

If the language does not support this ability, then I'd consult in order: You organisational naming conventions, the platform/language naming standards/conventions, the strict need to express this information at all in the name.

3
  • ... and the I for interface is far from being Hungarian notation. If it is required is surely debatable, but your arguments are weak. In an IDE, the "interface" will only reveal itself when one actively typing at the code (Intellisense, auto completion) or hovering with the mouse But try to post a code snippet on Stackoverflow and read it when you don't have your Visual Studio IDE at hand.
    – Doc Brown
    Mar 4 at 5:57
  • Yes true, I did in fact mean Hungarian not Polish.
    – Kain0_0
    Mar 4 at 7:34
  • It is true that it is debatable as to whether or not its needed. There is a threshold where more information is useful. So lets put it another way, I doubt you call your friend. FriendBob, you probably just call them Bob. That being said you might call them BachelorBob when that piece of information is important to convey, so I'm not against Hungarian notation itself, just poor usage of it. But that notation is best applied to the variable, not to the type name. Because in another Context it might be SickBob and obviously don't want to change the type for that.
    – Kain0_0
    Mar 4 at 7:41
2

There should be only one source of truth, and the truth should be in the code without unnecessary redundancy.

Names, like comments, can mislead: a class is named at a given time. But if it redundantly reflects some language feature used, what wound happen, if the design evolves? Of course, a class can be renamed when refactored. But compilers don’t check names, so, can you be sure that nobody forgot in a hurry to rename a class to match the new code? So better do not rely on the names to guess the language feature used and let your design remain free to evolve.

Examples:

  • What if a concreteElectricCar extends BaseCar and later you come to the conclusion one of its method should better be kept abstract: would the names BaseElectricCar and BaseCar make your code more understandable than ElectricCar and Car ?

  • what if finally you’d prefer composition over inheritance, and decide to make BaseCar concrete and inject a strategy to which the formerly abstract methods would forward the call?

  • More generally, Base suggests a minimalistic class that is expected to be extended. Not necessarily an abstract class.

6
  • 1
    Class names are part of the code, those are exactly the things in the code where choosing them meaningful and consistently matters. The "one source of truth" metapher is a recommendation against too much superfluous documentation, not against choosing class names following some convention.
    – Doc Brown
    Mar 4 at 11:02
  • @DocBrown indeed, strictly speaking, comments are also part of the code. I’ve clarified by extending my summary sentence. It’s a about redundancy and possible inconsistencies. Introducing a prefix in the name redundantly expresses what the class definition already does. This redundancy is superfluous. Moreover it may be misleading, since the compiler doesn’t check consistency of the name with the language constructs. Finally it is ambiguous: some reader will understand BaseCar as a minimalistic car without necessarilybeing abstract
    – Christophe
    Mar 4 at 12:38
  • And to this I would add: document your thoughts and decisions, whatever they may be, as a permanent part of the project's ongoing history and chronology. If, as is undoubtedly the case, "the team debated it," capture that. Formally. Mar 5 at 1:09
  • 1
    @MikeRobinson There are plenty of situations where there are two possible ways, and one of them looks a lot better but has some hidden problems that are bad and unfixable. Without documentation, every year or two someone will come and say "why didn't we use the much better method, I'll change that" until they figure out the hidden problems and go back to the old way.
    – gnasher729
    Mar 9 at 19:19
  • @gnasher729 I fully agree. Booch in this book of 1992 already explained that it makes sense to document things that cannot or not easily be found in code, such as complex interactions or rationale of important design decisions. My answer was focused on about the rest, and particularly misleading naming: nobody will check a naming in a design decision, especially of there seems to be nothing special about it.
    – Christophe
    Mar 9 at 20:12
1

I've seen various approaches to this over the years. If I see a class-name such as BaseCar or AbstractCar, then what this tells me ... as a human reader ... is that these classes are never instantiated.

But ... most languages expressly provide for this idea in the form of "Abstract Classes." This is a language-enforced rune which is independent of the class-name but often denoted by it, e.g. abstract class AbstractCar ...

1
  • As an example, Swift and Objective-C don't support classes where the compiler disallows instantiation. At best you can hide the constructor from anyone except the derived classes. Or make a function that should be unimplemented to call FatalError().
    – gnasher729
    Mar 9 at 19:20
0

Here is one reason why I dont like the usage of base inside name:

AbstractBaseJPAAuditIdEntity

This is exgaggeration , but I have seen my share of such names.

Unfortunatly very often such naming goes as being OK because the code NEEDS to be consistent. Sometimes I feel consistency is becoming an excuse of being stup#!?.

1
  • Yeah, "Hungarian Notation" (and so forth ...) can really become a hindrance. Mar 5 at 1:07
0

Whether it's a good idea or not is another discussion...

Yes, it is a reasonably common convention that a "Base" class is abstract, especially in .NET. A framework provides a concrete class that does something useful. It inherits from an abstract class with the same name plus the Base suffix.

For typical cases, you can use the concrete class. But dependencies elsewhere are defined using the ...Base class. That way, you have the opportunity to substitute your own custom class instead of their concrete one.

If there is nothing that must already be there, the framework would just provide an interface instead of the abstract class. The abstract class provides some minimal essential functionality.

A prime use is for a test double.

Examples in .NET

Microsoft.AspnetCore.Mvc.ControllerBase

HttpRequestBase and HttpResponseBase in the old .NET Framework 4.8 . Plain Microsoft.AspnetCore.Http.HttpRequest and Microsoft.AspnetCore.Http.HttpResponse are abstract in .NET 5

Microsoft.Dynamics.Commerce.Runtime.DataModel.AttributeBase

1
  • The System.Web classes have been superseded in .NET Core. They removed the "Base" suffix in those classes. The Microsoft Dynamics classes, however, I'm not sure about. I assumed the "Base" suffix was used to rectify collisions of class names in multiple namespaces, when they expected both HttpRequest and HttpRequestBase to be used in the same source code file. This was common in ASP.NET MVC. Mar 5 at 16:25

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.