Good design goes hand in hand with the nomenclature it uses for exchanging that design between developers. A key feature to writing good code consists of good naming conventions and consistency to ensure that the code will be reusable.
The purpose of any class that you design should be apparent from its name. In addition, it will help the reader if your class indicates whether it is an interface, an abstract class, or a concrete implementation class.
You can christen the type of your class based on its "abstractness." Let's look at a simple inheritance example. Consider a class whose purpose is to manage something. We would definitely want to have the String "Manager" in its name. The definition of the hierarchy for this class consists of defining an interface, an abstract class that partially implements it (i.e., provides the implementation for some of its methods), and a concrete class that completes the implementation of the interface. The nomenclature should be as follows:
public interface ManagerIfc
public abstract class ManagerBase implements Manager
public class ManagerImpl extends Manager
If other programmers look at this code and know your conventions, they can easily determine where in the hierarchy the class falls. An "Ifc" suffix indicates an interface; "Base" means an abstract class; "Impl" means an implementation. Only the class with the "Impl" suffix can be instantiated.
What if there are multiple implementations? In that case, the name should indicate what is the main characteristic of the implementation and the class "ManagerImpl" should just be a default implementation. For example, if we have "Product Managers" and "Project Managers," we should name them as:
public class ProductManagerImpl extends Manager
public class ProjectManagerImpl extends Manager