开发者_开发知识库
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 8 years ago.
Improve this questionWhy use package visibility (the default), unless the class should be public in java
As Rostislav Matl said, it's useful for when you want to make something that doesn't form part of your package's interface.
As an example, imagine you have a package and it provides an interface and at least one concrete implementation of a service.
People who use this service are going to care about the interface you provide and use one of the concrete classes you provide but they aren't going to care about much else beyond that. Our service has to talk to a database and it needs to be able to map the result from database queries into its own data type (that form its contract).
I find that I regularly create package private helper classes that contain utility type methods or perform tasks like the mapping that we need. Default (package private) visibility is perfect for this because other classes inside your package can use these helpers but no-one outside the package can see them so you're free to change them whenever you like.
This is a an example using some code:
We have our interface:
public interface UsefulService {
Collection<DataThings> getThings(Identifier id);
}
...and our concrete implementation:
public class JdbcUsefulServiceImpl implements UsefulService {
//We can break the code for the mapping out into its own class
private Mapper mapper;
@Override
public Collection<DataThings> getThings(Identifier id){
DatabaseQueryResult queryResult = //Code to hit a database and return objects from that domain model
Collection<DataThings> result = mapper.mapFromDatabaseToServiceDomain(queryResult);
return result;
}
}
Then we have our mapper. We don't need anyone outside the package to care about the service works internally so we use package private visibility and we can have as many classes as we want to get the job done:
class Mapper {
Collection<DataThings> mapFromDatabaseToServiceDomain(DatabaseQueryResult queryResult){
//magic to map objects goes here
}
}
The benefit that we have is that we can always change this Mapper class however we want or delete it or create new package private classes and we know the only (immediate) effects we can cause are inside this package. By immediate effects I mean compiler errors and serious things like that. Obviously you could break your service if you change its behaviour but that's what your automated test suite is there to catch :P
My understaning is package/default access is for package internals, i.e. classes that do not form package interface, i.e. classes that should not be used outside the package.
精彩评论