A module has access to the entire OpenMRS api and its objects. A module is able to simply make calls through the static Context class to fetch objects from the database and to save objects to the database. Code doing this acts in a module just as it would in the core api or core webapp.
A module also has access to services and objects in other modules if it marks those other modules as "required modules" in its own config.xml file. OpenMRS ensures that all of a module's 'required modules' are loaded before loading the module.
A module can override or just listen to all service calls made within OpenMRS. This is done through AOP and Spring. A module simply has to create an advice class and register that class as OpenMRS advice in its config.xml file.
A module can override any jsp page in the core OpenMRS webapp. If a jsp page in the "mappings" element in the moduleApplicationContext.xml is the same as the mappings element in the core openmrs-servlet.xml file, only the firstly registered mapping will exist in OpenMRS. Be sure to set the "order" element on your mapping to be less than the order on the openmrs-servlet.xml (currently 99) to have your module's jsp mapping loaded before the core mapping.
A module can simply append content to a core OpenMRS jsp page if that jsp page has an extensionPoint on it already. See extension points for information on how to set up an extension in your module to an extensionPoint.