I have an abstract class that will have many implementors. There are, of course, many places to put abstract classes in a Java package structure. Should the abstract class be in the same package as the implementors, or should it be in an "abstract package" package, or somewhere else? Please explain why you would place it there - I'm looking for design discussion, not just what I should do in this particular case.
I would put it (like any other class) in the package it belongs most from it's content. That mostly - but not everytime - means, that you put it in the same package as implementing classes. Sometimes you put an abstract class in the same package as some other class using this abstract class - it's part of the API of the other class. Implementing classes could be somewhere else in that case. I never use extra packages for abstract classes or other stuff like exception-classes or so.
Why so? I prefer to use package-structure as building a system for categorizing the content of the software, instead as using it for implementation details. The abstract-class may become later a valid non-abstract-class without breaking the API. But if I have to move it's package it would break again old code. Unnessecary I think.
I was just wondering about the same thing (but for interface classes). So lets add a post to this discussion.
I have a package
com.cie.devices where I put devices which I control using Java software. Now comes the time where there are enough devices to start building a hierarchy of devices. I was wondering if I should put my
TypeA interface for type A devices in
com.cie.devices.typea, together with implementing classes. My main argument for not doing so was that putting interfaces in
com.cie.devices made it easy to quickly identify all types of devices by looking at the interfaces in that package. My main argument for doing so is that it brings all type A related classes together.
In the end, I guess I'll all type related devices in the same package (i.e. all type A in
com.cie.devices.typea) because 1) you already quickly see all types of devices looking at the subpackages of
com.cie.devices, and 2) it unclutters the
com.cie.devices packages which will probably still contain some lonely classes which do not have enough friends to be pushed a level lower in the class hierarchy.
So that's it. This is another case with another reasoning behind it.