[java] Interface naming in Java

Most OO languages prefix their interface names with a capital I, why does Java not do this? What was the rationale for not following this convention?

To demonstrate what I mean, if I wanted to have a User interface and a User implementation I'd have two choices in Java:

  1. Class = User, Interface = UserInterface
  2. Class = UserImpl, Interface = User

Where in most languages:

Class = User, Interface = IUser

Now, you might argue that you could always pick a most descriptive name for the user implementation and the problem goes away, but Java's pushing a POJO approach to things and most IOC containers use DynamicProxies extensively. These two things together mean that you'll have lots of interfaces with a single POJO implementation.

So, I guess my question boils down to: "Is it worth following the broader Interface naming convention especially in light of where Java Frameworks seem to be heading?"

This question is related to java interface naming-conventions

The answer is


There may be several reasons Java does not generally use the IUser convention.

  1. Part of the Object-Oriented approach is that you should not have to know whether the client is using an interface or an implementation class. So, even List is an interface and String is an actual class, a method might be passed both of them - it doesn't make sense to visually distinguish the interfaces.

  2. In general, we will actually prefer the use of interfaces in client code (prefer List to ArrayList, for instance). So it doesn't make sense to make the interfaces stand out as exceptions.

  3. The Java naming convention prefers longer names with actual meanings to Hungarian-style prefixes. So that code will be as readable as possible: a List represents a list, and a User represents a user - not an IUser.


Is this a broader naming convention in any real sense? I'm more on the C++ side, and not really up on Java and descendants. How many language communities use the I convention?

If you have a language-independent shop standard naming convention here, use it. If not, go with the language naming convention.


Following good OO principles, your code should (as far as practical/possible) depend on abstractions rather than concrete classes. For example, it is generally better to write a method like this:

public void doSomething(Collection someStuff) {
    ...
}

than this:

public void doSomething(Vector someStuff) {
    ...
}

If you follow this idea, then I maintain that your code will be more readable if you give interfaces names like "User" and "BankAccount" (for example), rather than "IUser", "UserInterface", or other variations.

The only bits of code that should care about the actual concrete classes are the places where the concrete classes are constructed. Everything else should be written using the interfaces.

If you do this, then the "ugly" concrete class names like "UserImpl" should be safely hidden from the rest of the code, which can merrily go on using the "nice" interface names.


Is there really a difference between:

class User implements IUser

and

class UserImpl implements User

if all we're talking about is naming conventions?

Personally I prefer NOT preceding the interface with I as I want to be coding to the interface and I consider that to be more important in terms of the naming convention. If you call the interface IUser then every consumer of that class needs to know its an IUser. If you call the class UserImpl then only the class and your DI container know about the Impl part and the consumers just know they're working with a User.

Then again, the times I've been forced to use Impl because a better name doesn't present itself have been few and far between because the implementation gets named according to the implementation because that's where it's important, e.g.

class DbBasedAccountDAO implements AccountDAO
class InMemoryAccountDAO implements AccountDAO

In my experience, the "I" convention applies to interfaces that are intended to provide a contract to a class, particularly when the interface itself is not an abstract notion of the class.

For example, in your case, I'd only expect to see IUser if the only user you ever intend to have is User. If you plan to have different types of users - NoviceUser, ExpertUser, etc. - I would expect to see a User interface (and, perhaps, an AbstractUser class that implements some common functionality, like get/setName()).

I would also expect interfaces that define capabilities - Comparable, Iterable, etc. - to be named like that, and not like IComparable or IIterable.


In C# it is

public class AdminForumUser : UserBase, IUser

Java would say

public class AdminForumUser extends User implements ForumUserInterface

Because of that, I don't think conventions are nearly as important in java for interfaces, since there is an explicit difference between inheritance and interface implementation. I would say just choose any naming convention you would like, as long as you are consistant and use something to show people that these are interfaces. Haven't done java in a few years, but all interfaces would just be in their own directory, and that was the convention. Never really had any issues with it.


There is also another convention, used by many open source projects including Spring.

interface User {
}

class DefaultUser implements User {
}

class AnotherClassOfUser implements User {
}

I personally do not like the "I" prefix for the simple reason that its an optional convention. So if I adopt this does IIOPConnection mean an interface for IOPConnection? What if the class does not have the "I" prefix, do I then know its not an interface..the answer here is no, because conventions are not always followed, and policing them will create more work that the convention itself saves.


=v= The "I" prefix is also used in the Wicket framework, where I got used to it quickly. In general, I welcome any convention that shortens cumbersome Java classnames. It is a hassle, though, that everything is alphabetized under "I" in the directories and in the Javadoc.

Wicket coding practice is similar to Swing, in that many control/widget instances are constructed as anonymous inner classes with inline method declarations. Annoyingly, it differs 180° from Swing in that Swing uses a prefix ("J") for the implementing classes.

The "Impl" suffix is a mangly abbreviation and doesn't internationalize well. If only we'd at least gone with "Imp" it would be cuter (and shorter). "Impl" is used for IOC, especially Spring, so we're sort of stuck with it for now. It gets a bit schizo following 3 different conventions in three different parts of one codebase, though.


Bob Lee said once in a presentation:

whats the point of an interface if you have only one implementation.

so, you start off with one implementation i.e. without an interface. later on you decide, well, there is a need for an interface here, so you convert your class to an interface.

then it becomes obvious: your original class was called User. your interface is now called User. maybe you have a UserProdImpl and a UserTestImpl. if you designed your application well, every class (except the ones that instantiate User) will be unchanged and will not notice that suddenly they get passed an interface.

so it gets clear -> Interface User implementation UserImpl.


As another poster said, it's typically preferable to have interfaces define capabilities not types. I would tend not to "implement" something like a "User," and this is why "IUser" often isn't really necessary in the way described here. I often see classes as nouns and interfaces as adjectives:

class Number implements Comparable{...}  
class MyThread implements Runnable{...}
class SessionData implements Serializable{....}

Sometimes an Adjective doesn't make sense, but I'd still generally be using interfaces to model behavior, actions, capabilities, properties, etc,... not types.

Also, If you were really only going to make one User and call it User then what's the point of also having an IUser interface? And if you are going to have a few different types of users that need to implement a common interface, what does appending an "I" to the interface save you in choosing names of the implementations?

I think a more realistic example would be that some types of users need to be able to login to a particular API. We could define a Login interface, and then have a "User" parent class with SuperUser, DefaultUser, AdminUser, AdministrativeContact, etc suclasses, some of which will or won't implement the Login (Loginable?) interface as necessary.


Examples related to java

Under what circumstances can I call findViewById with an Options Menu / Action Bar item? How much should a function trust another function How to implement a simple scenario the OO way Two constructors How do I get some variable from another class in Java? this in equals method How to split a string in two and store it in a field How to do perspective fixing? String index out of range: 4 My eclipse won't open, i download the bundle pack it keeps saying error log

Examples related to interface

Cast object to interface in TypeScript When to use Interface and Model in TypeScript / Angular Is there a way to create interfaces in ES6 / Node 4? Can a normal Class implement multiple interfaces? When to use: Java 8+ interface default method, vs. abstract method How should I have explained the difference between an Interface and an Abstract class? When do I have to use interfaces instead of abstract classes? How to extend a class in python? Interface type check with Typescript Abstract Class vs Interface in C++

Examples related to naming-conventions

How to name Dockerfiles What is the difference between .yaml and .yml extension? Is there a naming convention for git repositories? What's the name for hyphen-separated case? Should I use "camel case" or underscores in python? Is there a naming convention for MySQL? What is the javascript filename naming convention? REST URI convention - Singular or plural name of resource while creating it What is the standard naming convention for html/css ids and classes? What are naming conventions for MongoDB?