2010-08-03 18 views
10

1) ¿Por qué en los archivos que están en un paquete Java debo escribir el "paquete" en él ?, no se asume indirectamente que si está en el directorio, ¿está en el paquete ?.¿Por qué palabra clave "paquete" y .h?

2) Vengo del mundo de C++. Siempre importé la .h de las clases que necesito de otros archivos que usan esa clase (quiero decir, solo quiero "mostrar" el encabezado, no la implementación). Pero ahora estoy un poco confundido acerca de las importaciones en Java. ¿Cómo se hace esto en Java?

Gracias

Respuesta

7
  1. no, eso no se asume. Después de todo, ¿cuál es mi paquete llamado? com.mypackage.stuff? s rc.com.mypackage.stuff? myproject.com.mypackage.stuff? C.Users.makakko.workspace.myproject.src.com.mypackage.stuff?

    Si solo basa el paquete en las carpetas, ¿está relacionado con la raíz de la unidad? ¿Qué pasa si el proyecto se desarrolla en una letra de unidad diferente en una máquina diferente? ¿Es relativo a la ubicación de javac.exe? Una vez más, ¿qué pasa con los diferentes directorios de instalación? ¿Qué pasa con el directorio de trabajo cuando se ejecuta javac? Pero puede especificar una ubicación para que javac encuentre sus archivos de origen. Qué sucede si quiere hacer un programa de prueba simple, o enseñar a alguien Java que nunca ha programado antes; ¿tiene que usar/explicar todo el concepto de estructura del paquete?

    Si omite el especificador package, entonces todavía está en un paquete. Es solo el "paquete predeterminado", que no tiene nombre.

  2. Los archivos de encabezado son más un artefacto de la forma en que C necesita compilarse que una forma de lograr ocultar la información. En C, se debe definir un método antes de poder hacer referencia a él. Si desea tener varios métodos que se refieran entre sí, debe definirlos todos antes de usar alguno de ellos, de ahí el encabezado. Los encabezados en C++ se transfieren de eso, pero los cambios en C++ alteran la necesidad de encabezados.

    En Java, el compilador examinará todos sus métodos y firmas de clase antes de hacer algo que requiera el método/clase. La función servida por los encabezados se coloca en el compilador.No se puede confiar en la cabecera para su ocultación de información, porque

    1. El código puede ser colocado dentro de un archivo de cabecera

    2. A menos que utilice información real que oculta como una biblioteca independiente, un programador puede ir encontrar el archivo C/CPP que coincide con la cabecera sin la edición

    mismo modo en Java, sólo se puede obtener información real que oculta mediante la eliminación de la fuente. Una vez que ha hecho que la fuente sea inaccesible, expone la API con clases, enums e interfaces públicas/protegidas. Para obtener puntos de bonificación, escriba comentarios explicativos de JavaDoc para todo y ejecute javadoc.exe sobre su fuente para producir documentación independiente para cualquier persona que use su paquete (s).

+0

AFAIK el nombre del paquete siempre es redundante. Simplemente intente cambiar 'com.mypackage.stuff' por * anything * else y compilarlo sin cambiar' CLASSPATH'. – maaartinus

5

1) La declaración package tiene que coincidir con la jerarquía de directorios en el proyecto.

Si uso package com.stackoverflow.bakkal; en Car.java, se espera la siguiente jerarquía.

com/ 
|-- stackoverflow/ 
| `-- bakkal/ 
|  |-- Car.java 

2) Si desea ocultar una aplicación puede utilizar interface en Java en lugar de un class. A continuación, distribuya las implementaciones reales en archivos .class o JAR, por ejemplo.

Mmm sino una interfaz no se pueden crear instancias ...

La interfaz funciona como un prototipo en C++, en cierta medida. Usted tiene el contrato, entonces la implementación real proviene de otro lugar.

Quiero crear una instancia de una clase, pero sin dar la implementación, sólo el prototipo

eso no es posible, incluso C++, ¿cómo se puede crear una instancia de algo sin tener su aplicación real? En C++, aún necesitaría vincular los archivos del objeto. En Java, usa los archivos .class.

+1

1) Mi pregunta es por qué no se asume? : S 2) Mmm pero no se puede instanciar una interfaz ... Quiero instanciar una clase, pero sin dar la implementación, solo el prototipo. – makakko

+0

@makakko: Siempre que el archivo .java esté disponible, la implementación siempre estará disponible. Período. Si desea ocultar la implementación, proporcione al usuario/programador/ET únicamente archivos .class (o .jar que contenga .class). Sin embargo, asegúrese de incluir documentación. –

+0

Gracias Brian, lo tengo. :). Por cierto, la .class se puede revertir de una manera "agradable", es decir, restaurar las funciones/variables de "nombre" originales? Porque supongo que Java VM no maneja los "offsets" para los miembros de la clase o las funciones ... – makakko

3

No se asumen los paquetes porque la filosofía de Java es que es mejor ser explícito que implícito/supuesto.

Le da la posibilidad de acceder a cualquier cosa en su paquete actual, pero cualquier elemento externo debe ser importado explícitamente. (Creo que Java.lang es la excepción porque contiene tanta funcionalidad base como String que no habría un solo paquete que no la usaría).

Esta es también la razón por la que se mire:

import java.util.ArrayList; 
import java.util.LinkedList; 

en lugar de:

import java.util.*; 

Esto puede parecer molesto, hasta el día en que están tratando de averiguar alguien código vigilara y golpea usted cuánto más difícil sería si las cosas estuvieran ocultas/implícitas.

Si usa Eclipse, Netbeans o IntelliJ, nunca lo notará debido a dos características.

En primer lugar, si presiona ctrl-space en medio de escribir un nombre de clase, no solo completará el nombre de la clase, sino que también lo agregará automáticamente a la lista de importaciones.

En segundo lugar, si alguna vez llega a donde las importaciones son "Incorrectas" o no utiliza la expansión ctrl-space, puede simplemente escribir ctrl-shift-o (eclipse) para tener "Fix imports". Esto importará automáticamente cosas que necesitan importar y eliminar importaciones que ya no necesita. Dependiendo de su configuración, también expandirá o colapsará * 's.

Una vez que obtenga un sistema inactivo, nunca considerará las importaciones.

1

El paquete especifica una ruta a la clase. Debe coincidir con el directorio en el disco o en el jar (zip). La ubicación es relativa a una ubicación en el classpath. El acceso protegido está restringido a las clases en el mismo paquete.

Algunas de las cosas que puede hacer en un archivo .h se realizan en la definición de clase. Las constantes pertenecen a una clase y pueden ser públicamente visibles. En a .h las constantes deben ser públicamente visibles.

Importar es el equivalente a incluir un .h, pero ayuda a tratar los problemas de las definiciones conflictivas del mismo nombre. Puede incluir solo un elemento o todos los elementos visibles de una clase. También es posible omitir la importación y usar el nombre del paquete para prefijar la clase a la que está accediendo.

La implementación no es realmente visible a través de una importación (Al menos no más allá de la proporcionada por la clase compilada. Lo que es visible son los métodos y datos públicos de la interfaz visible. Para importaciones desde el mismo paquete, métodos y datos que no tienen acceso especificado (público/protegido/privado) también son visibles. Los métodos y variables protegidos son visibles para las subclases de la clase. Los archivos .h pueden utilizarse sin proporcionar archivos de origen o de objeto. Las importaciones requieren que se proporcionen las clases especificadas. (Una clase puede consistir únicas constantes, aunque eso sería ser un mal diseño.)

+0

acceso 'protected' significa subclases, no el mismo paquete. El acceso al paquete (también "acceso predeterminado") se especifica al omitir cualquier palabra clave de acceso (pública/protegida/privada). –

+0

La respuesta ha sido corregida. – BillThor

Cuestiones relacionadas