Documente Academic
Documente Profesional
Documente Cultură
Programación Java
Enero de 2020
ÍNDICE
Módulo 1.- Fundamentos de OOP .................................................................................. 5
Introducción ................................................................................................................. 6
Abstracción ................................................................................................................... 6
Tipos de abstracción .................................................................................................... 6
Objetos .......................................................................................................................... 7
Relevancia de un objeto ............................................................................................... 8
Independencia de un objeto ........................................................................................ 8
Atributos y operaciones ............................................................................................... 8
Encapsulamiento .......................................................................................................... 9
Partes de un objeto encapsulado................................................................................. 9
Implementación del encapsulamiento ...................................................................... 10
Mensajes ...................................................................................................................... 10
Clases ........................................................................................................................... 12
Generalización ............................................................................................................ 12
Herencia ...................................................................................................................... 13
Polimorfismo............................................................................................................... 13
Clase abstracta ........................................................................................................... 14
Módulo 2.- Fundamentos de Java ................................................................................. 15
Antecedentes ............................................................................................................... 16
Los productos de la tecnología Java ......................................................................... 16
Componentes del J2SDK Estandar Edition............................................................. 17
Ciclo de elaboración de programas en Java ............................................................ 17
Palabras reservadas ................................................................................................... 18
Espacios en blanco ..................................................................................................... 18
Identificadores ............................................................................................................ 19
Separadores ................................................................................................................ 20
Comentarios ................................................................................................................ 20
Bloques de código ....................................................................................................... 21
Tipos de datos primitivos de Java ............................................................................ 21
Valores literales .......................................................................................................... 22
Identificación de los componentes de una clase....................................................... 23
Declaración de una clase............................................................................................ 24
Declaración e inicialización de los atributos de una clase ...................................... 24
Declaración de los métodos de una clase .................................................................. 25
Declaración e inicialización de las variables de un método .................................... 26
Métodos de inicialización dinámicos ........................................................................ 27
Constantes ................................................................................................................... 27
El método main( ) ....................................................................................................... 28
Mi primer programa en Java .................................................................................... 28
Declaración, instanciamiento e inicialización de objetos ........................................ 28
Operadores matemáticos ........................................................................................... 31
Operadores relacionales ............................................................................................ 32
Operadores condicionales.......................................................................................... 33
Prioridad de operadores ............................................................................................ 34
Tomas de decisión ...................................................................................................... 34
Enunciado switch ....................................................................................................... 36
Ciclo for ....................................................................................................................... 38
Ciclo while ................................................................................................................... 39
Ciclo do/while ............................................................................................................. 40
Sentencias de salto ...................................................................................................... 41
Ciclos infinitos ............................................................................................................ 42
Promoción y casting de datos .................................................................................... 43
Cuidados en el manejo de datos enteros y reales .................................................... 45
Almacenamiento de variables, referencias y objetos en memoria ......................... 47
Uso de la clase String ................................................................................................. 48
Conceptos avanzados sobre invocación de métodos ............................................... 49
Declaración e invocación de métodos con argumentos y valores de retorno ........ 51
Creación de métodos y atributos estáticos ............................................................... 52
Métodos con sobrecarga ............................................................................................ 53
Encapsulamiento de atributos y métodos ................................................................ 54
Métodos Get y Set ...................................................................................................... 55
Alcance de las variables ............................................................................................. 57
Métodos constructores ............................................................................................... 58
El constructor por default ......................................................................................... 59
Sobrecarga de constructores ..................................................................................... 59
Arreglos unidimensionales ........................................................................................ 60
El atributo length ....................................................................................................... 62
Almacenamiento de arreglos unidimensionales en memoria ................................. 63
Empleo de ciclos con arreglos ................................................................................... 64
Empleo del arreglo de argumentos en el método main........................................... 64
Arreglos bidimensionales .......................................................................................... 66
Paso de argumentos de tipo objeto ........................................................................... 67
Retorno de valores de tipo objeto ............................................................................. 69
Implementación de herencia ..................................................................................... 69
Sobrescritura de métodos y atributos ...................................................................... 71
Métodos abstractos .................................................................................................... 73
Los constructores y la herencia................................................................................. 73
Acceso a miembros de una superclase...................................................................... 77
Importación de paquetes de clases ........................................................................... 77
Conceptos avanzados de encapsulamiento .............................................................. 79
Protección de acceso para clases ............................................................................... 80
Módulo 1.- Fundamentos de OOP
Lenguajes de programación Fundamentos de OOP
Introducción
El análisis y diseño Orientado a Objetos, es un paradigma desarrollado con la intención de
resolver un sin número de problemas, inclusive la programación de sistemas computacionales. Es
un concepto relativamente nuevo que emplea lo mejor de la programación estructurada clásica y
le añade una funcionalidad mayor, dado que divide la complejidad de un sistema entero en
pequeños módulos manejables y reutilizables gracias a un método conocido como abstracción.
Muchos lenguajes modernos como el C++ y Java toman ventaja del OOP.
El OOP modela a los sistemas (sean basados en software o no) tratándolos como una serie
de objetos que interactúan entre sí, de forma muy similar a como la gente común ve su medio
ambiente.
Abstracción
Abstraer significa “ignorar los detalles y centrarse en lo esencial”. La abstracción es la
forma elemental de enfrentarse con algo complejo y promueve el reúso dado que las
características específicas que hacen a cada objeto menos “genérico”, son ignoradas. La
Abstracción simplifica la manera en que los usuarios interactúan con los objetos.
Así, la abstracción se concentra en las partes más importantes de los objetos, como lo son
su significado y sus funciones (qué es y para qué sirve) pero ignorando los detalles innecesarios
(cómo es que lo hace).
Por ejemplo: Si observamos a un gato doméstico y a un gato montés, notaremos que ambos
tienen garras, pelo, bigotes y cuatro patas. Sin embargo, estos detalles no muestran las diferencias
entre ellos, ya que los gatos domésticos son mascotas y los monteses son animales salvajes.
Tipos de abstracción
Existen dos tipos de abstracción: La abstracción funcional, y la abstracción de datos.
La abstracción funcional se caracteriza por ocultar los detalles acerca del procesamiento de
los datos; en otras palabras, la forma en que un proceso se realiza permanece oculta. Por ejemplo,
cuando usted visita un restaurante y ordena un platillo, no necesita decirle al mesero cómo
preparar cada ingrediente, ya que el chef conoce perfectamente la receta. Así, las principales
características de la abstracción funcional son:
6
Lenguajes de programación Fundamentos de OOP
La abstracción de datos es similar a la funcional, excepto que esta trabaja con los datos y
sus tipos. Permite que los detalles de cómo un dato es representado internamente sean ignorados.
Por ejemplo, si usted desea representar una fecha, podría hacerlo con tres cantidades: Una para el
día, otra para el mes y otra para el año; o podría usar una cadena para representar el nombre del
mes y números para el día y el año. En cualquier caso, a usted no le interesa la manera en que
esos datos son almacenados en memoria, o de hecho, cómo son empleados en operaciones
matemáticas. Por esto último se dice que la abstracción de datos involucra también a la
abstracción funcional. En resumen, la abstracción de datos:
Objetos
Un objeto es una abstracción de la realidad. Dicho de manera más formal, un objeto es una
entidad discreta que contiene tanto estructuras de datos como un comportamiento definido. Más
coloquialmente, un objeto es una pequeña caja negra con funcionalidad propia, que cuenta con
una total independencia del código que lo utiliza o hace referencia a él.
Los objetos pueden ser simples o complejos, reales o imaginarios. Una antena parabólica es
un objeto complejo y real; un empleado (representación de los detalles y actividades de una
persona) es un objeto imaginario. A los objetos reales se les conoce también como concretos, y a
los imaginarios como conceptuales.
• Son cosas.
• Son simples o complejos.
• Son reales o imaginarios.
7
Lenguajes de programación Fundamentos de OOP
Relevancia de un objeto
Una vez que se han seleccionado todos los posibles objetos de un dominio, se les debe
evaluar para asegurarse de que son válidos. Generalmente se emplea el siguiente criterio:
Identificar los objetos de un sistema no es una ciencia, es un arte. Mientras que los objetos
a incluir deben cumplir con los criterios antes establecidos, dependen aún del contexto y del
punto de vista de la persona que realiza el modelo y de los usuarios del sistema a modelar. Como
ayuda extra para determinar si el objeto es relevante al sistema, pregúntese lo siguiente:
Independencia de un objeto
Como se mencionó antes, para que un objeto sea un objeto y no un atributo de otro objeto,
deberá existir de manera independiente en el contexto del problema abordado. Los objetos
pueden conectarse entre sí y aún poseer una existencia independiente.
Atributos y operaciones
Los objetos poseen atributos y operaciones. Los atributos (también llamados propiedades)
son sus características y las operaciones (también llamados métodos) son lo que el objeto puede
hacer. Suponga que una nube es un objeto; sus atributos serían tamaño, forma, color y sus
operaciones serían llover, nevar y relampaguear.
8
Lenguajes de programación Fundamentos de OOP
Todo objeto posee una identidad de manera inherente, por lo tanto, aunque dos objetos
posean los mismos atributos, se considerarán objetos diferentes.
Objeto Gato
Atributos Operaciones
Color de ojos Ronronear
Color de pelo Cazar ratones
Numero de patas Desgarrar el sillón
Raza Comerse las plantas
Encapsulamiento
Encapsular significa separar los aspectos externos de un objeto que son accesibles al
mundo exterior, de los detalles de implementación interna del mismo, los cuales deberán estar
ocultos. El encapsulamiento tiene una enorme ventaja: Siempre y cuando la interfase permanezca
igual, un objeto puede en un futuro cambiar sin afectar al resto del sistema, dado que los demás
objetos desconocen (y para el caso no les importa) la forma en que funciona internamente el
objeto que están usando.
La idea es la siguiente: Los objetos deben poder usarse aún cuando no se sabe a ciencia
cierta qué contienen; lo único que deberá preocuparnos es qué necesita el objeto para funcionar
y qué es lo que debemos esperar del mismo.
Suponga que un teléfono es un objeto en su sistema. ¿Se ha puesto a pensar alguna vez
cómo es que un teléfono comunica a las personas en ambos extremos? Lo más seguro es que no,
dado que lo anterior no es necesario para llamar por teléfono. A usted lo único que le debe
preocupar es cómo emplear la interfase del teléfono, que está compuesta por los botones, el
auricular y el micrófono.
Más aún, si su teléfono ayer era analógico y hoy es digital, usted aún puede usarlo de la
misma forma para hacer llamadas, siempre y cuando siga contando con botones, auricular y
micrófono.
• Interfaz pública: La parte externa del objeto que se usa para interactuar con el
mismo.
• Implementación: Las operaciones internas del objeto; esto es, qué se puede hacer
con él y cuál es su propósito.
• Información interna: Lo que el objeto debe saber para realizar su implementación.
9
Lenguajes de programación Fundamentos de OOP
En los sistemas orientados a objetos puros, todos los atributos son privados y pueden ser
cambiados o accedidos únicamente mediante operaciones a través de la interfaz pública. La
obtención y establecimiento de los atributos para la implementación son operaciones
comúnmente realizadas con dicha interfaz.
Por ejemplo: Para cambiar un radio a una estación en particular, el usuario presionará o
moverá el dial (operación en la interfaz pública) que causará que el sintonizador interno del radio
(implementación) se sincronice con la estación deseada (atributo privado). Así, el usuario puede
cambiar la estación del radio sin saber cómo es que el radio ubica la señal.
Mensajes
Se entiende por mensaje a la forma en que un objeto accede o se comunica con otro.
Consiste básicamente de dos partes: El nombre de la operación y sus argumentos. Así, un objeto
A (emisor) le envía un mensaje al objeto B (receptor) cuando necesita que realice alguna acción o
le retorne alguna información.
Cuando un objeto recibe un mensaje, lleva a cabo la operación que le fue requerida
ejecutando uno de sus métodos; en la práctica, no son más que algoritmos específicos cuyo
nombre es igual al del método invocado.
Los mensajes son parte de la interfaz pública y los métodos son parte de la implementación.
Al conjunto de mensajes a los que un objeto puede o sabe responder, se les denomina entonces
comportamiento o interfaz del objeto.
10
Lenguajes de programación Fundamentos de OOP
Caso de Estudio
Instrucciones: Lea el siguiente caso de estudio y posteriormente resuelva los ejercicios anexos:
La compañía Avon vende ropa por catálogo. El negocio está creciendo a un promedio de
30% anual y requieren de un nuevo sistema de entrada de pedidos. Usted ha sido contratado por
Avon para diseñar el nuevo sistema.
Los catálogos de ropa se producen mensualmente y son enviados por correo a los
suscriptores. Dichos catálogos cuentan con una sección para artículos en liquidación, ofertas del
mes y para los artículos a precio regular. Cada artículo del catálogo puede etiquetarse con un
precio diferente mes con mes, así que cuando un cliente hace un pedido, debe conocerse el
catálogo del cual está ordenando para identificar el precio correctamente. Si el catálogo del
cliente tiene más de seis meses de antigüedad, entonces el precio deberá actualizarse según el
catálogo más reciente.
Para realizar un pedido, los compradores pueden llamar a un representante de ventas, enviar
la orden por correo o faxearla. Una vez recibidas las órdenes son ingresadas al sistema por un
capturista.
Avon desea expandirse y le gustaría darle al comprador la opción de realizar sus pedidos en
línea vía Internet. Los artículos disponibles en línea estarían entonces disponibles y tendrían
asociado el precio del catálogo actualizado. Después de que la orden se introduce en el sistema,
deberá verificarse en inventario y de ser posible asignado inmediatamente. Si el artículo no está
en inventario, pero ya ha sido solicitado al proveedor, entonces la orden se pondrá en estado de
espera hasta que sea surtido.
Una vez que la orden esté completa, se verificará el pago y se enviará al departamento de
empaques en donde se le preparará para su envío. Avon acepta como forma de pago cheques y
tarjeta de crédito.
11
Lenguajes de programación Fundamentos de OOP
Clases
Se define como clase a un grupo de objetos que comparten los mismos atributos y
operaciones. El principio a seguir es el siguiente: Cuando múltiples objetos cuentan con la misma
estructura de datos (Atributos) y comportamiento (Operaciones) se pueden aglutinar para formar
una clase. Así, se dice que todo objeto es una instancia de su clase. Las clases no son objetos,
sólo los describen; funcionan como una plantilla.
Una clase podrá contener un conjunto infinito de objetos individuales, conteniendo un valor
propio para cada uno de sus atributos, pero compartiendo el nombre de dichos atributos y las
mismas operaciones con el resto de su clase. Todo objeto contiene una referencia implícita a su
propia clase; en otras palabras, sabe la clase de objeto que es.
Generalización
Cuando se habla de objetos, es conveniente clasificarlos en grupos con atributos y
operaciones en común. Por ejemplo, la clase Medio de Transporte podría contener a los objetos
Tren, Automóvil, Bicicleta o Caballo. El hecho de que todos estos medios de transporte operen
de manera diferente puede ser irrelevante para el análisis que se está haciendo; por ejemplo, si
Medio de Transporte implica únicamente la acción de trasladarse de un lugar a otro, entonces la
implementación específica para hacerlo no importa y las características de la clase Medio de
Transporte podrán re usarse en todas las clases que la comprenden.
Persona
Medio de
Transporte
Cliente Empleado
Tren Avión Automóvil
RDV Capturista
12
Lenguajes de programación Fundamentos de OOP
Herencia
Un término asociado directamente a la generalización es la herencia. Se entiende por
herencia el que clases diferentes con una relación jerárquica compartan atributos y operaciones.
Para ello, se deberá definir una clase que posteriormente se irá refinando produciendo subclases.
Así, las subclases generadas poseerán o heredarán todas y cada una de las propiedades de su clase
superior o superclase, añadiendo además sus propiedades exclusivas.
Polimorfismo
Se entiende como polimorfismo al hecho de que una misma operación pueda comportarse
de manera diferente en distintas clases. Por ejemplo, suponga que tenemos a la clase Pelota y a
las subclases Pelota de Soccer y Pelota de Tenis y que ambas clases tienen la operación Lanzar.
La forma en que se lanza una pelota de soccer es con ambas manos y hacia el frente en el saque
de banda, mientras que la de tenis se lanza hacia arriba con una sola mano en el servicio.
Para que exista polimorfismo deberá existir herencia y obtenerse el mismo resultado
semántico; de lo contrario se trata únicamente de una operación con el mismo nombre. En
resumen:
• Las subclases que redefinen una operación heredada para reflejar de manera más
exacta las acciones propias están proveyendo otra forma a la operación, de ahí el
término polimorfismo.
Caso de Estudio
Usando a la Internet como fuente principal de información, clasifique a los objetos Perro y
Lobo partiendo de la superclase Seres Vivos. Incluya la mayor cantidad de clases intermedias
posibles, indicando las características distintivas de dichas clases.
13
Lenguajes de programación Fundamentos de OOP
Clase abstracta
Cuando las operaciones o métodos de una clase son tan generales que es casi imposible
definir una implementación, se dice que dicha operación es abstracta. Cualquier clase con al
menos una operación de este tipo es llamada clase abstracta. Por este motivo, las clases
abstractas no se pueden instanciar.
Suponga que se requiere implementar clases para los objetos Círculo, Rectángulo y
Triángulo; dichas clases deberán poseer las operaciones Fijar Color y Estilo de Borde. Dado que
cada figura realiza estas acciones de forma completamente diferente, se decide crear una
superclase abstracta Figura Geométrica que contenga dos operaciones abstractas llamadas Fijar
Color y Estilo de Borde pero que no provean ninguna implementación. Cuando las clases
Círculo, Rectángulo o Triángulo hereden de la clase Figura Geométrica las operaciones
anteriores, deberán redefinirlas dado que estas no poseen código de implementación alguno.
14
Módulo 2.- Fundamentos de Java
Lenguajes de programación Fundamentos de Java
Antecedentes
El lenguaje de programación Java (llamado inicialmente Oak) se originó en 1991 como
parte de un proyecto de investigación para desarrollar un lenguaje capaz de romper el vacío de
comunicación existente entre muchos productos electrónicos de consumo general, como los
hornos de microondas, las televisiones y las videograbadoras. Dado que el concepto original
falló, el equipo de programadores que diseñó este lenguaje (conocido formalmente como el
Green Team) se vio obligado a encontrarle otro uso.
Afortunadamente el world wide web comenzó a ser más popular y el lenguaje Oak probó
ser ideal para desarrollar pequeños componentes que permitieran enriquecer con multimedia el
contenido de las páginas de Internet. Estas pequeñas aplicaciones conocidas hoy en día como
applets, se convirtieron en la punta de lanza de lo que en breve sería el lenguaje de programación
más usado del mundo.
16
Lenguajes de programación Fundamentos de Java
• Generación el código fuente: Los códigos fuente Java pueden capturarse usando el
editor de texto de su preferencia (como el Bloc de Notas de Windows). Su extensión
deberá ser .java y su nombre tendrá que coincidir exactamente con el de la clase
que esté conteniendo.
• Compilación del código fuente: Para compilar un código Java basta con
posicionarse en la ruta en donde se encuentra el compilador e invocarlo mediante la
sentencia: javac nombredearchivo.java. El resultado será un archivo
binario altamente optimizado interpretable por la JVM (conocido popularmente
como bytecode) con extensión .class.
• Ejecución del bytecode: Para ejecutar un programa de Java se necesita invocar a la
JVM mediante la sentencia: java nombredearchivoclase. Dado que el
resultado de la compilación de un programa en Java no es un código ejecutable
directamente por la plataforma de nuestro equipo, se dice que Java es un lenguaje
interpretable.
17
Lenguajes de programación Fundamentos de Java
ruta de búsqueda por defecto del sistema, por lo que puede invocarse desde cualquier unidad o
ruta local.
Palabras reservadas
Como todo lenguaje de programación, Java posee un conjunto de palabras reservadas (48
en total) que no pueden ser usadas para nombrar ningún identificador:
Cabe hacer notar que, aunque las palabras const y goto están reservadas, no se utilizan.
Adicionalmente, Java emplea los nombres true, false y null para definir los valores
constantes falso, verdadero y nulo respectivamente, por lo que tampoco pueden emplearse para
definir identificadores propios.
Espacios en blanco
En Java, un espacio entre dos palabras, un tabulador o un carácter de nueva línea son
considerados un espacio en blanco. Los espacios en blanco son obligatorios únicamente para
delimitar elementos del código que no están separados de antemano por algún operador o
separador válido.
Cualquier forma de indentación que usemos tendrá entonces como único objetivo hacer
nuestro código más legible, mas no tendrá efecto en el código mismo (a no ser que se encuentre
dentro de una cadena literal, en cuyo caso se considerará parte de la misma).
if (i > 5)
System.out.println(“Y es mayor que 5”);
18
Lenguajes de programación Fundamentos de Java
Y que:
if(
i>
5)
System.
out.println
(“Y es mayor que 5”
)
;
Es inválido sin embargo dividir identificadores, palabras reservadas o cadenas literales con
caracteres de nueva línea; lo siguiente por ejemplo causaría un error de compilación:
System.out.println(“Y es mayor
que 5”);
Para separar una cadena literal en dos líneas, coloque una diagonal invertida ( \ ) antes del
carácter de nueva línea de la siguiente forma:
System.out.println(“Y es mayor\
que 5”);
Tome en cuenta sin embargo que la indentación que precede al segundo renglón de la
cadena se considerará parte de la cadena misma.
Identificadores
Un identificador es un nombre creado por el programador para dar nombre a variables,
métodos, clases y objetos. Las reglas generales a seguir son las siguientes:
• Todos los identificadores deberán empezar con una letra, un carácter de subrayado
( _ ) o un símbolo de moneda ( $ ). Después del primer carácter se permite el uso de
dígitos numéricos; no se permite emplear símbolos de puntuación, caracteres
especiales o espacios en blanco. Las mayúsculas y minúsculas son distinguibles y
no hay límite de longitud.
Ejemplos:
MyFirstClass ItemOnSale loopCounter webServerURL itemPrice
19
Lenguajes de programación Fundamentos de Java
Separadores
La tabla siguiente muestra los separadores del lenguaje Java:
Comentarios
Se emplean comentarios para determinar fácilmente qué se hace en cada parte de nuestro
programa. Existen dos formas de comentarios:
• De una sola línea: El marcador // le indica al compilador que ignore lo que sigue
hasta el final de la línea actual.
• De varias líneas: Estos son los tradicionales comentarios usados en programación;
el marcador /* le dice al compilador que ignore cualquier cosa hasta que se
encuentre con un marcador de terminación */.
/**************************************
*Esta clase no hace ABSOLUTAMENTE NADA*
**************************************/
20
Lenguajes de programación Fundamentos de Java
Bloques de código
Un bloque de código es la agrupación de una o más sentencias encerradas entre un par de
llaves ({}). Una vez creados, los bloques se comportan como una unidad lógica indivisible, tal
cual y como si se tratara de una sola sentencia. Como se verá en el transcurso de este manual, los
bloques de código tienen múltiples propiedades y usos.
• Enteros, los cuales almacenan datos numéricos que no contienen punto decimal:
byte, short, int y long.
• De punto flotante o reales, los cuales almacenan datos numéricos que contienen
punto decimal: float y double.
• De carácter, los cuales almacenan el valor Unicode (http://www.unicode.org) del
carácter que se guarda en ellos: char. La siguiente liga contiene una práctica
calculadora para realizar conversiones:
http://code.cside.com/3rdpage/us/javaUnicode/converter.html.
• Lógicos, los cuales almacenan uno de dos valores lógicos (true o false):
boolean
En la siguiente tabla se muestra el tamaño en bits y el rango de valores aceptado por cada
uno de estos tipos de datos:
21
Lenguajes de programación Fundamentos de Java
NOTAS:
• Para almacenar más de un carácter se usan las variables de tipo String. Dado que
las cadenas no son tipos primitivos sino objetos, se describirán en un apartado más
adelante.
• Se recomienda (cuando la longitud del valor lo permita) utilizar el tipo double
para números reales y el tipo int para los enteros.
Valores literales
Un valor literal (como su nombre lo indica) es aquel que se escribe literalmente en nuestro
código; por ejemplo:
En este caso tenemos (de izquierda a derecha) un valor literal entero, uno de punto flotante,
uno de carácter y una cadena. Comúnmente, los valores literales se emplean cuando deseamos
asignar valores a nuestros identificadores; por ello, vale la pena tomar en cuenta lo siguiente:
Todos los valores literales enteros se consideran de tipo int a menos que se les anexe
como posfijo la letra L, en cuyo caso se considerarán de tipo long. Pueden expresarse también
en formato octal (precediéndolos de un cero) o hexadecimal (precediéndolos de un cero y una
equis minúscula o mayúscula).
Ejemplos:
Dado que no hay forma de especificar que una literal entera es de tipo byte o short, lo
único que deberá preocuparnos es que el valor literal no rebase los límites permitidos por el tipo
de dato en cuestión.
Por otra parte, todos los valores literales de punto flotante se consideran de tipo double a
menos que se les anexe como posfijo la letra F. Pueden expresarse también en notación científica
agregándoles como posfijo la letra ‘e’ minúscula o mayúscula y un entero positivo o negativo que
indique la potencia de 10 del exponente.
Ejemplos:
22
Lenguajes de programación Fundamentos de Java
Los valores literales de tipo char deben escribirse encerrados entre comillas simples
(‘‘). Cuando se trata de caracteres no imprimibles directamente desde el teclado, podremos
recurrir a una secuencia de escape con el formato que indica la tabla siguiente:
Ejemplos:
NOTA: Tome en cuenta que existe una equivalencia directa de valores entre la tabla ASCII
y la tabla UNICODE. De hecho, aunque legalmente los valores de tipo char no son
números, pueden tratarse como tales: Es posible inicializar un identificador de tipo carácter
asignándole el valor numérico correspondiente de la tabla ASCII o UNICODE; aún más,
con las debidas consideraciones pueden incluirse como operandos en expresiones
matemáticas unarias o binarias.
Por último están las literales de cadena, las cuales se especifican encerradas entre un par de
comillas dobles (“”); es posible incluir en una cadena tanto caracteres imprimibles como
secuencias de escape. Por ejemplo:
NOTA: Aunque el compilador no objete al respecto, una clase deberá contener al menos un
método o un atributo, ya que de lo contrario no tendrá razón de existir.
En donde:
Ejemplos:
public class Shirt public class Order public class SalesManager
Los atributos deben colocarse de manera obligatoria afuera de cualquier método. También
se les conoce como variables miembro o variables de instancia dado que cuando un objeto es
instanciado, estas variables se encargarán de contener los datos específicos de cada objeto creado
(en otras palabras, habrá una copia de ellas por objeto). Aunque inicialmente todas las variables
miembro de un objeto contendrán el mismo valor, esto podrá cambiar después.
24
Lenguajes de programación Fundamentos de Java
En donde:
Ejemplos:
En donde:
25
Lenguajes de programación Fundamentos de Java
• identificador será el nombre del método según las reglas vistas con
anterioridad.
• [argumentos] representa la lista de variables cuyos valores son pasados al
método para que éste trabaje y son opcionales. Los paréntesis de apertura “( “ y
cierre “ ) “ son obligatorios aún cuando el método no requiera ningún argumento.
• bloque_de_instrucciones será la lista de sentencias que el método ejecuta.
Una gran variedad de tareas puede realizarse en el bloque de código o cuerpo de un
método. Así como en otros lenguajes de programación, podrán crearse tantos
bloques de instrucciones internos como se desee o convenga.
• Las llaves de apertura y cierre ( { } ) delimitan el cuerpo de nuestro método.
Las variables locales pueden declararse con toda libertad en cualquier parte del bloque
principal de un método y existirán en memoria hasta que el método al que pertenecen perdure.
Como se verá más adelante, es posible incluso construir bloques anidados dentro del bloque
principal de un método con la finalidad de reducir el tiempo de vida de una variable. Sin
embargo, a pesar de lo anterior, no podrá haber dos variables locales con el mismo nombre en un
método dado.
tipo identificador;
identificador = valor;
En donde:
26
Lenguajes de programación Fundamentos de Java
Ejemplos:
double itemPrice;
int customerAge = 30;
float orderTotal = 99F
Al igual que con los atributos, es posible declarar e inicializar más de una variable local en
la misma línea empleando al separador coma; por ejemplo:
NOTAS:
El método main( )
Como se mencionó anteriormente, una aplicación de escritorio estará constituida por al
menos una clase llamada clase controladora, clase principal o clase de prueba que sirve de
punto de entrada al programa. La característica principal de esta clase es que debe contener al
menos un método y ese método deberá tener la siguiente sintáxis:
NOTAS: Sólo podrá haber un método main() por cada programa de consola. El nombre
de la cadena de argumentos args puede cambiarse si así de desea.
1. Definir la clase del objeto en un archivo fuente en donde se detallen sus atributos y
métodos.
2. Definir la clase principal que usará el o los objetos creados.
3. Declarar, instanciar e inicializar los objetos en la clase principal.
4. Invocar sus métodos de las instancias creadas.
Tomemos por ejemplo el siguiente código Java en donde se define a una clase de objeto
llamada Message:
Como podemos notar, esta clase no tiene atributo alguno y únicamente cuenta con un
método llamado printMessage(), el cual no retorna o recibe ningún valor, únicamente
imprime un mensaje.
28
Lenguajes de programación Fundamentos de Java
Dado que esta clase no contiene un método main(), será imposible ejecutarla, únicamente
podremos compilarla. Para usarla, deberemos crear una clase principal o de prueba que
llamaremos MessageTest en donde crearemos una instancia del objeto de clase Message e
invocaremos su único método:
En el código anterior notamos una sintaxis nueva en la tercera línea; ésta es la declaración,
instanciamiento e inicialización de un objeto de clase Message. La sintaxis genérica es la
siguiente:
En donde:
nombredeclase identificador;
identificador = new nombredeclase();
Message myMessage;
myMessage = new Message();
Por último, analicemos la cuarta línea; aquí invocamos el método del objeto empleando una
sintaxis genérica:
identificadordeobjeto.identificadordemétodo();
Dado que la sintaxis completa que se emplea para invocar un método varía
considerablemente según la situación, se verá con detalle en un apartado más adelante.
NOTA: Contrario a como sucede en C o C++, Java no permite el uso de apuntadores por
parte del programador. Lo anterior podría verse como una desventaja aunque en realidad es
todo lo contrario: gracias a que no puede haber manipulación de memoria es imposible
29
Lenguajes de programación Fundamentos de Java
Ejercicio 1
Capture los siguientes códigos, compílelos y ejecútelos. Identifique las partes de las clases
a manera de repaso.
Ejercicio 2
1. Diseñe y cree una clase llamada Customer.java que contenga los siguientes
atributos (usted decida el tipo): customerID, customerName,
customerStatus y totalPurchases.
2. Asigne a dichos atributos un valor por omisión al momento de declararlos. El
atributo customerStatus podrá tener dos valores: ‘N’ para Nuevo y ‘V’ para
Viejo.
3. Diseñe dentro de la clase un método que imprima los valores por omisión que usted
asignó. Llame al método displayCustomerInfo.
30
Lenguajes de programación Fundamentos de Java
Operadores matemáticos
Java emplea los siguientes operadores matemáticos:
Unarios
Propósito Operador Ejemplo
Pre-incremento ++var ++i
Post-incremento var++ i++
Pre-decremento --var --i
Post-decremento var-- i--
Binarios
Propósito Operador Ejemplo
Suma + x+y
Resta - x-y
Multiplicación * x*y
División / x/y
Módulo % x%y
Asignación
Propósito Operador Ejemplo
Asignación directa = i = 2
Compuestos
Propósito Operador Ejemplo
Suma y asignación += i += 2
Resta y asignación -= i -= 2
Multiplicación y asignación *= i *= 2
División y asignación /= i /= 2
Módulo y asignación %= i %= 2
int x = 1, y = 1;
System.out.println(“Valor de x: “ + ++x);
System.out.println(“Valor de y: “ + y++);
System.out.println(“Valor de x + y: “ + (x+y));
Valor de x: 2
Valor de y: 1
Valor de x + y: 4
a = a + 4;
a += 4;
Por otra parte, el operador de asignación posee un atributo interesante: permite realizar
asignaciones en cadena; por ejemplo:
int x, y, z;
x = y = z = 100;
Operadores relacionales
Los operadores relacionales comparan dos valores para determinar su relación; la siguiente
tabla muestra los operadores relacionales disponibles en Java:
El resultado de una operación relacional será siempre un valor booleano (true o false)
y se emplean con mayor frecuencia en las operaciones condicionales y ciclos.
32
Lenguajes de programación Fundamentos de Java
NOTA: No use el operador de “igual que” con datos de tipo String dado que el resultado
obtenido será erróneo; recuerde que las cadenas son objetos y por lo tanto no estaría usted
comparando su contenido sino sus referencias. Para comparar cadenas recurra al método
equals como se ve a continuación:
Operadores condicionales
Se pueden emplear los operadores condicionales (también conocidos como operadores
lógicos) para construir expresiones booleanas más complejas:
La siguiente tabla muestra los valores de verdad para los operadores AND, OR, XOR y
NOT empleando dos expresiones:
Como podrá notar en la primera tabla, Java provee un segundo conjunto de operadores
AND y OR conocidos como operadores en cortocircuito. Estos operadores se llaman así porque
la expresión de la derecha no se evalúa cuando el resultado de la operación queda determinado
por el valor de verdad de la expresión de la izquierda.
33
Lenguajes de programación Fundamentos de Java
Prioridad de operadores
La siguiente tabla muestra la prioridad por omisión de los operadores vistos hasta el
momento:
Los operadores relacionales tienen menor precedencia que los matemáticos; a su vez, los
operadores condicionales tienen menos precedencia que los relacionales, a excepción de la
negación, cuya jerarquía es igual a la de los operadores matemáticos unarios.
Tomas de decisión
El enunciado básico de control de programa es el enunciado if; su forma sencilla es:
if (expresión_booleana){
bloque;
}
34
Lenguajes de programación Fundamentos de Java
if (expresión_booleana){
bloque;
}
else{
bloque;
}
Dentro de bloque podrán incluirse cualquier tipo y cantidad de enunciados, inclusive otro
enunciado if; a esto último se le conoce como anidación.
Ejemplo:
if (x == y)
System.out.println("x es igual a y");
else
if (x > y)
System.out.println("x es mayor que y");
else
System.out.println("x es menor que y");
Ejercicio 3
1. Diseñe y cree una clase llamada Person.java que contenga el atributo
ageInYears. Asigne a dicho atributo un valor de inicio diferente de cero.
3. Diseñe una clase principal llamada PersonTest.java que cree un objeto de tipo
Person e invoque a su método para desplegar su edad en dias.
Ejercicio 4
1. Diseñe y cree una clase llamada CalculateDays.java que contenga el atributo
público month con valor inicial de cero.
2. Diseñe dentro de la clase un método que calcule y despliegue el número de días que
tiene un mes dado.
35
Lenguajes de programación Fundamentos de Java
Enunciado switch
Este es el enunciado de control más flexible de Java, ya que permite que el programa
ejecute diferentes bloques de instrucciones basado en una expresión que puede tener más de dos
valores. Su sintaxis es la siguiente:
switch (variable){
case plantilla_1: bloque_1;
break;
case plantilla_2: bloque_2;
break;
...
case plantilla_n: bloque_n;
break;
[default: bloque_default;]
}
En donde variable podrá ser cualquier variable de tipo byte, short, int o char.
Dicha variable se compara contra cada plantilla y:
La plantilla podrá estar constituida por una constante entera o por valores literales
válidos, pero nunca variables o llamados a métodos. En caso de buscar coincidencia con
caracteres, deberán estar encerrados en comillas simples. Es de suma importancia el agregar un
enunciado break después del último enunciado de cada plantilla, ya que de lo contrario todos
los enunciados posteriores pertenecientes a las plantillas restantes, se ejecutarán también. Esto
debe evitarse, a menos que sea útil a nuestros fines.
Ejemplo 1:
switch (opcion){
case 1: System.out.println("Seleccionó Altas!");
break;
case 2: System.out.println("Seleccionó Bajas!");
break;
case 3: System.out.println("Seleccionó Cambios!");
break;
default: System.out.println("Fuera de rango!!!");
}
36
Lenguajes de programación Fundamentos de Java
Ejemplo 2:
switch (opcion){
case 1:
case 2:
case 3:
case 4:
case 5: System.out.println("Introdujo 5 o menos!");
break;
case 6:
case 7:
case 8:
case 9:
case 10: System.out.println("Introdujo 10 o menos!");
break;
default: System.out.println("Fuera de rango!!!");
}
Ejemplo 3:
switch (opcion){
case 'a': System.out.println("Seleccionó Altas!");
break;
case 'b': System.out.println("Seleccionó Bajas!");
break;
case 'c': System.out.println("Seleccionó Cambios!");
break;
default: System.out.println("Fuera de rango!!!");
}
Ejemplo 4:
switch (contador){
case 1: switch(var){
case 0: System.out.println("var vale cero");
break;
case 1: System.out.println("var vale uno");
break;
}
break;
case 2: System.out.println("No hubo conflictos!”);
break;
default: System.out.println("Fuera de rango!!!");
}
Ejercicio 5
• Adapte el ejercicio cuatro para que la toma de decisión sea realizada por un
enunciado switch y no por toma de decisiones anidadas.
37
Lenguajes de programación Fundamentos de Java
Ciclo for
Este ciclo es una construcción que ejecuta un bloque de uno o más enunciados una
determinada cantidad de veces. En Java, tiene la siguiente estructura:
En donde:
• inicial será por lo general una expresión de asignación que ponga una variable a
un valor determinado de inicio y dicha variable será típicamente la que controle el
ciclo; de hecho, como normalmente no se emplea para ninguna otra función, se
acostumbra declarar dicha variable en este punto. La expresión inicial se ejecuta una
sola vez al entrar al ciclo.
• expresión_booleana será la expresión a evaluar; el ciclo se ejecutará mientras
sea verdadera y terminará cuando sea falsa.
• incremento será la expresión que determine el incremento o decremento de la
variable controladora. Esta expresión se ejecutará al final de cada iteración mientras
el ciclo continúe activo.
• bloque será el o los enunciados a realizar en el ciclo; como se vio anteriormente,
cuando se trate de un solo enunciado, podrá prescindirse de las llaves.
Ejemplos:
Los anteriores son ejemplos típicos de utilización de un ciclo for que demuestran que la
variable controladora puede ser incrementada o decrementada, y no necesariamente en una
unidad. Sin embargo, su flexibilidad es mucho mayor; por ejemplo, la variable controladora no
necesariamente debe ser inicializada dentro del ciclo:
int count = 1;
for ( ; count < 1000; count++)
Esto permite que el lugar que la inicialización ocupa, sea utilizado para incluir cualquier
expresión válida de Java:
count = 1;
for ( System.out.println("Contando..."); count < 100; count++)
Además, el incremento o decremento puede ser hecho en cualquier otra parte del ciclo:
38
Lenguajes de programación Fundamentos de Java
Por último, es posible dividir las expresiones de inicio e incremento en dos o más
subexpresiones utilizando el separador coma, haciéndolo trabajar como un operador y
permitiéndonos realizar varias tareas al mismo tiempo:
Al igual que una instrucción condicional, un ciclo for puede ser ejecutado dentro de otro,
logrando así una construcción más compleja y efectiva:
Ejercicio 6
• Diseñe una clase llamada Factorial.java que contenga un método capaz de
calcular y desplegar el factorial de su atributo público number, al cual usted
asignará un valor desde la clase principal FactorialTest.java.
• Diseñe la clase principal de tal forma que pruebe la clase Factorial al menos
con tres valores diferentes.
• Diseñe el método de cálculo de tal forma que no acepte valores menores a 1 o
mayores a 30.
Ciclo while
Este ciclo es una construcción que ejecuta un bloque de uno o más enunciados mientras que
una condición específica sea cierta. En Java, tiene la siguiente estructura:
while(expresión_booleana){
bloque;
}
En donde:
• bloque será el o los enunciados a realizar en el ciclo; al igual que en un ciclo for,
cuando se trate de un solo enunciado no se requieren de las llaves.
Ejemplos:
x = 0;
while(x < 10){
System.out.println("El valor de x es: " + x);
x++;
}
Al igual que los ciclos for, un ciclo while puede ser ejecutado dentro de otro:
Ciclo do/while
A diferencia del ciclo while, el ciclo do/while evalúa la condición al final del ciclo en
vez de hacerlo al principio; por ello, son siempre ejecutados al menos una vez. Su forma es:
do{
bloque;
}
while(expresión_booleana);
Ejemplo:
x = 10;
do
System.out.println("El valor de x es: " + x);
while(x != 10);
40
Lenguajes de programación Fundamentos de Java
Como se puede apreciar, al igual que en todos los casos anteriores, las llaves no son
requeridas en bloques de una sola línea. Paralelamente, los ciclos do/while aceptan también la
anidación.
Ejemplo:
Sentencias de salto
Java incorpora tres sentencias de salto diferentes: break, continue y return; se les
llama así dado que transfieren o devuelven el flujo de ejecución a otra parte del programa.
break:
Ejemplo:
NOTA: Cuando se trate de un ciclo anidado, break causará la salida del ciclo más interno
únicamente.
41
Lenguajes de programación Fundamentos de Java
continue:
Ejemplo:
return:
La sentencia return da por terminado el método que se está ejecutando en ese momento,
devolviendo el control del flujo al método que lo invocó originalmente; si se ubica en el método
main(), el programa terminará regresando el control al sistema operativo.
Ejemplo:
class Return{
public static void main(String args[]){
boolean t = true;
System.out.println(“Antes del return”);
if(t)
return;
System.out.println(“Esto es código muerto!!!”);
}
}
NOTA: La sentencia return nos permite (además de dar por concluido un método)
retornar un valor. Esto se verá con más detenimiento más adelante.
Ciclos infinitos
Un ciclo infinito es aquel for, while o do/while que por sí solo, se ejecutará
indefinidamente; aunque esto es una anomalía que debe evitarse, a veces puede ser útil, si se
42
Lenguajes de programación Fundamentos de Java
utiliza correctamente en combinación con uno o varios enunciados break. En Java, un ciclo
infinito se redacta como sigue:
Para evitar esto, las variables y las expresiones podrán ser promovidas a un tamaño mayor;
la promoción podrá ser manual (realizada por el programador) o automática (realizada por el
compilador. La otra opción es ajustar el tamaño de las expresiones para coincidir con la variable;
a este método de ajuste se le conoce formalmente como type casting.
Promoción:
Aparentemente esto debería de funcionar, dado que un dato de tipo byte es capaz de
contener el valor del resultado; sin embargo el compilador arrojará el siguiente error:
43
Lenguajes de programación Fundamentos de Java
Esto sucede dado que un dato byte es menor que un dato int; para esta situación la
promoción manual es la solución más sencilla, dado que sólo habría que redefinir el tipo de dato
de num3:
int num 3;
Sin embargo en algunos casos (si la variable es de un tipo mayor al de la expresión que se
le pretende asignar) el compilador realiza la promoción de la expresión de manera automática;
esto sucede dado que se asume que no existirá pérdida de datos. Suponga por ejemplo la siguiente
asignación directa:
long bigNumber = 6;
Como recordará, las literales numéricas enteras se consideran por omisión de tipo int.
Siendo este el caso, se realizará una promoción automática a tipo long al momento de la
compilación, como si se le hubiese adicionado el posfijo L al número seis. Lo mismo sucede
cuando pretendemos asignar un dato de tipo entero (char, byte, int o long) a uno de tipo
real (float o double). Dado que no hay posiciones decimales en los enteros, no hay datos que
perder.
NOTA IMPORTANTE
long num3;
num3 = 55555 * 66666L;
Casting:
Ahora bien, cuando no es deseable cambiar el tipo de dato de la variable que habrá de
contener nuestra asignación, será necesario ajustar el tamaño de esta última por medio de un
44
Lenguajes de programación Fundamentos de Java
En donde:
NOTA: Emplee el casting con cuidado cuando se trate de datos reales que tengan una parte
fraccional, puesto que esta será truncada por completo (a menos que eso sea lo que usted
pretende). De igual manera tome en cuenta que los datos de tipo entero serán recortados si
se les ajusta a un tipo menor dentro de su categoría.
Cuando los datos primitivos son enteros se convierten a tipo int (a menos que
específicamente se diga que son de tipo long) antes de realizarse cualquier operación
matemática; suponga por ejemplo:
short a, b, c;
a = 1; b = 2;
c = a + b;
Lo anterior causa un error dado que aunque a y b se declararon como short, los valores 1
y 2 son convertidos a int antes de sumarse. Para librar el problema podríamos:
45
Lenguajes de programación Fundamentos de Java
Por otra parte, cuando los datos primitivos son de tipo real se convierten a tipo double (a
menos que específicamente se diga que son de tipo float). La siguiente línea por ejemplo
causaría un error de compilación, dado que por omisión 27.9 es considerado un double:
Ejercicio 7
• Diseñe una clase llamada Primo.java que contenga un método capaz de definir
si un número de tipo long es o no primo. El número a definir deberá almacenarse en
el atributo público number, al cual usted asignará un valor desde la clase principal
PrimoTest.java.
• Diseñe la clase principal de tal forma que pruebe la clase Primo al menos con tres
valores diferentes.
46
Lenguajes de programación Fundamentos de Java
Memoria Memoria
Stack Heap
Los objetos con sus atributos son almacenados en la memoria Heap, la cual es administrada
de manera dinámica por el programa. Por otra parte, las referencias a los objetos y las variables
de sus métodos son almacenadas en la memoria Stack, dado que sólo son empleadas por un breve
periodo de tiempo. Mientras que las variables de tipo primitivo almacenan valores, las referencias
a objetos almacenan la ubicación en memoria (dirección) de los mismos.
Dichas ubicaciones, generalmente escritas en notación hexadecimal, son únicas para cada
objeto instanciado y se crean dinámicamente en tiempo de ejecución. Considere el siguiente
código:
0 shirtID
0.0 price
U colorCode
counter 10
0x034009
myShirt 0x034009
47
Lenguajes de programación Fundamentos de Java
Por lo anterior, tome en cuenta que cuando usted asigna el valor de una referencia a objeto
a otra no estará pasando los valores de los atributos de un objeto a otro. Lo que en realidad
sucederá es que ambas referencias contendrán ahora la misma dirección (esto es, apuntarán al
mismo objeto). Por ejemplo:
0 shirtID
0.0 price
U colorCode
counter 10
0x034009
0x034009 0 shirtID
myShirt 0x99F311
0.0 price
0x99F311
48
Lenguajes de programación Fundamentos de Java
La primera forma es por supuesto más común, dada su sencillez y similitud con las
declaraciones de variables simples. Como cualquier objeto, las cadenas hacen uso de espacio en
la memoria stack para almacenar la referencia y de la memoria heap para almacenar su
contenido; sin embargo, cuando son creadas sin la palabra clave new, las cadenas se almacenan
en una parte especial del heap conocida como el pool de literales (literal pool). Esta área
reservada tiene la característica de no permitir la duplicación de cadenas idénticas.
myString
0xDEF 0x0011F [C Value
0x2244C Comparator
0xDEF
Luis Muslera
0x0011F
Por último, tome en cuenta que en Java las cadenas son objetos inmutables (esto es, no se
pueden modificar). Una vez creado un objeto String no se pueden alterar los caracteres que lo
conforman. Cuando usted iguala un identificador a una cadena diferente Java crea un objeto
nuevo en el Heap y modifica la referencia empleada, dejando en manos del recolector de basura
la destrucción de la cadena original.
identificadordeobjeto.identificadordemétodo();
En donde:
49
Lenguajes de programación Fundamentos de Java
Por ejemplo:
Lo anterior es posible porque cuando no se especifica el nombre del objeto al que el método
pertenece, Java antepone por omisión la palabra clave this, que le indica al programa que el
método se encuentra en la misma clase. Podemos dejar que el compilador asigne la palabra clave
por omisión o podemos hacerlo nosotros manualmente; por ejemplo:
this.displayShirtInformation();
50
Lenguajes de programación Fundamentos de Java
En donde:
Cualquier tipo de dato puede usarse como argumento o valor de retorno (String
inclusive). Sin embargo, aunque un método podrá aceptar cualquier número de parámetros, sólo
podrá tener un valor de retorno.
Ejemplos:
Para invocar a un método con argumentos, simplemente agregue en el paréntesis los valores
requeridos en el orden especificado; tome en cuenta que los tipos y la cantidad de argumentos
deben coincidir. Por ejemplo:
suma(5,10);
setID(550);
De igual forma que pueden emplearse valores literales, es posible emplear nombres de
variables como argumentos válidos. Una vez más, los tipos y el número de argumentos deberán
coincidir con los esperados por el método.
NOTA: Un método podrá aceptar como argumentos y retornar valores de tipo objeto; lo
anterior sin embargo requiere de un análisis más detallado, por lo que se verá con
detenimiento en un apartado posterior.
Hasta ahora se han empleado métodos que no retornan nada y emplean a void como
tipoderetorno. Cuando desee que un método retorne un valor, especifique el tipo antes del
nombre del método e incluya una sentencia de retorno en su cuerpo con la siguiente sintaxis:
return expresión;
51
Lenguajes de programación Fundamentos de Java
En donde expresión podrá ser una literal, una variable o una operación matemática.
Podrá haber más de una sentencia de retorno por método siempre y cuando estén posicionadas
estratégicamente en sentencias de toma de decisión. Por ejemplo:
if (a > b)
return “A es mayor que B”;
else
return “B es igual o mayor que A”;
El valor de retorno de un método worker podrá o no ser utilizado por el método caller
según se requiera; para emplear un valor de retorno, el llamado al método deberá estar redactado
en una sentencia de asignación o ser usado directamente como parámetro de otro método. Para el
código anterior (suponiendo que esté incrustado en un método compare con valor de retorno
String, en un objeto llamado numbers) podríamos hacer lo siguiente:
String message;
message = numbers.compare();
System.out.println(message);
O también:
System.out.println(numbers.compare());
Por otro lado, se ha estado empleando en las clases principales un método especial llamado
main() que no requiere ser instanciado. Lo anterior es posible dado que el método main() es
un método estático (también conocidos como métodos de clase) y estos pueden ser invocados sin
necesidad de instanciar primero el objeto que los contiene.
De la misma manera, Java permite crear atributos estáticos que pueden emplearse sin
necesidad de instanciar el objeto que los contiene.
Dado que los métodos estáticos no forman parte de cada instancia de objeto, no se deberá
emplear una referencia a objeto para invocarlos, sólo su clase. Así, la sintaxis quedaría como
sigue:
Identificadordeclase.identificadordemétodo([argumentos]);
52
Lenguajes de programación Fundamentos de Java
Shirt.convertSize(25);
Por otra parte, las variables de clase estáticas, se emplean cuando se requiere únicamente
una copia de la misma variable en memoria para todos los objetos instanciados, no una copia por
cada objeto. De la misma forma que los métodos estáticos, un atributo estático se declara
agregándole el modificador static; por ejemplo:
Así mismo, se deberá emplear el nombre de la clase para acceder a las variables estáticas:
Identificadordeclase.identificadordevariable
Por ejemplo:
De hecho, los atributos estáticos pueden ser además constantes si se les agrega el
modificador final; la variable PI por ejemplo, es una variable de clase pública, estática y final
que pertenece a la clase Math. Tome además en cuenta que un método estático definido en una
clase sólo puede emplear sus atributos cuando estos son también estáticos.
• Realizar una operación en un objeto dado o asociar una variable con un tipo de
objeto específico no es importante.
• Acceder la variable o el método antes de instanciar el objeto es importante.
• El método o variable no pertenece de manera lógica a un objeto, pero
probablemente pertenezca a una clase de utilería, como System o Math (incluidas
en el API de Java). Esta última de hecho, contiene diversos métodos estáticos que
pueden emplearse en ecuaciones matemáticas.
Ejercicio 8
• Diseñe una clase pública llamada Mate.java que contenga un método estático
capaz de calcular y desplegar el factorial de un número entero que se le pase a
manera de argumento. El método deberá tener como valor de retorno el factorial
calculado.
• Diseñe una clase principal de tal forma que pruebe el método de cálculo del
factorial de la clase anterior.
• Diseñe el método de cálculo de tal forma que no acepte valores menores a 1 o
mayores a 30.
53
Lenguajes de programación Fundamentos de Java
Por ejemplo, es probable que se desee crear un método que sume dos cantidades (por
ejemplo, dos datos de tipo int o dos datos de tipo float). Con una sobrecarga de método esto
puede hacerse sin mayor problema como en el ejemplo siguiente:
Cuando se invoque el método sum(), bastará con colocar los argumentos requeridos por
cualquiera de las tres combinaciones; el compilador comparará la firma del llamado con la de la
declaración del método y elegirá el que corresponda. Suponga una clase principal para la clase
anterior como la siguiente:
Los métodos y atributos de una clase pueden tener modificadores como public, que le
indican al compilador el nivel de acceso que otros objetos pueden tener hacia ellos. El otro
modificador más comúnmente usado es private.
54
Lenguajes de programación Fundamentos de Java
Como es de imaginarse, public permite acceso al atributo o método desde la misma clase
o desde otras clases. Eso significa que el método podrá ser invocado y el atributo podrá ser
modificado por cualquiera; tan sólo agregue la palabra clave public como modificador del
atributo o método en cuestión:
En la mayoría de los casos, sin embargo, es preferible que sólo algunos o ninguno de los
atributos de un objeto sean públicos, sino todo lo contrario. Esto es, que sólo puedan ser
modificados dentro de la clase que los contiene. Lo anterior cobra más sentido cuando
recordamos que un objeto sabe mejor que nadie cómo se comporta, y que de hecho la forma en
que lo hace no debería de importarnos; únicamente nos debe incumbir cómo emplearlo.
De hecho, los métodos y atributos públicos de un objeto son llamados con frecuencia la
interfaz de la clase, puesto que son la única forma de interactuar con los objetos que se creen en
base a ella.
Los detalles de cómo una clase realiza una operación dada dentro de un método son
llamados la implementación del método.
Dado que las principales operaciones a realizar con los atributos de un objeto es cambiarles
su valor (Set Value) u obtener su valor (Get Value), es común que todo objeto cuente con al
menos un método público para cada una. Suponga la siguiente clase de ejemplo:
55
Lenguajes de programación Fundamentos de Java
La anterior clase define cinco atributos privados y dos métodos públicos: Uno para obtener
el código de color de la camisa y otro para cambiarle el código de color a la camisa. La clase de
prueba podría quedar como sigue:
En este caso, se obtiene el color de la camisa, luego se intenta cambiar por un valor no
válido (lo cual despliega un error) y por último se le asigna otro valor (esta vez válido) para
después desplegarse en pantalla. Como puede observarse, en ningún momento se menciona
siquiera el nombre del atributo colorCode, ya que de eso se encargan los métodos públicos.
Como cultura general: Los métodos para obtener y cambiar atributos de un objeto son
llamados con frecuencia métodos getter y métodos setter, respectivamente.
Ejercicio 9
• Diseñe una clase llamada Customer.java que contenga atributos privados para
almacenar el nombre completo, ID, teléfono y dirección de correo de un cliente. La
clase deberá contener métodos getter y setter para establecer y desplegar dichos
atributos.
• Diseñe una clase principal de tal forma que pruebe los métodos getter y setter de la
clase anterior.
56
Lenguajes de programación Fundamentos de Java
Hasta el momento hemos visto que los atributos se declaran al principio de la clase
(después de su encabezado y antes del primer método) permitiendo que sean usados a través del
objeto entero (si son privados) o por todos los objetos (si son públicos). Más delante se verán dos
formas más para especificar el ámbito de los atributos de una clase.
Las variables locales por el contrario, serán accesibles únicamente dentro del método en el
cual fueron declaradas y perdurarán en memoria mientras el método se esté ejecutando. De
manera más precisa, se dice que una variable local será visible únicamente en el bloque de
instrucciones que la contiene (permitiéndose la anidación de bloques) y su tiempo de vida será
igual al del bloque mismo.
Cuando un bloque se anida dentro de otro, las variables del bloque externo serán visibles
dentro del bloque interno, pero no a la inversa; considere como ejemplo el siguiente código:
Dado que la variable x fue declarada en el bloque principal del método main, será visible
también dentro del bloque interno. La variable y por el contrario no podrá ser referenciada fuera
de dicho bloque puesto que se declaró dentro de él.
NOTA: Contrario a como se permite en C o C++, no podrán existir dos variables locales
con el mismo nombre en el mismo método aunque pertenezcan a ámbitos diferentes.
Por su misma naturaleza, las variables locales no pueden ser estáticas ni públicas; sólo
pueden hacerse constantes con la palabra clave final. Cualquier intento por referenciar a una
variable local desde otro método u objeto causará un error de compilación.
Se puede dar el caso en que una variable local posea el mismo nombre que un atributo de la
clase en que el método se encuentra. Dadas las reglas de alcance, cuando enunciamos el
identificador de la variable estaremos haciendo referencia a la variable local, no al atributo.
Métodos constructores
Un constructor es un método que tiene el propósito especial de instanciar a un objeto de una
manera definida. Generalmente son empleados para asignar valores de inicio a sus atributos y se
invocan de manera automática; su sintaxis es similar a la de un método:
[modificadores] Nombredelconstructor([argumentos]){
bloque;
}
En donde:
58
Lenguajes de programación Fundamentos de Java
Como puede apreciarse, el método constructor Shirt recibe como parámetro un código de
inicio a ser validado posteriormente. El siguiente podría ser un código válido para una clase
principal de prueba:
Al declarar nuestro propio constructor sin embargo, el constructor por default no será
insertado más en nuestra clase, por lo que si se desea tener uno, habrá que declararlo
explícitamente. Tan sólo declare otro constructor dentro de su clase que no acepte parámetros;
por ejemplo:
public Shirt(){
...
...
}
Sobrecarga de constructores
La razón por la cual podrá existir más de un constructor en una clase dada es porque, como
los métodos, los constructores pueden sobrecargarse. Lo anterior ofrece una gran variedad de
opciones para inicializar nuestros objetos proporcionando distintos parámetros al momento de
crearlos. Tome como muestra el siguiente código:
59
Lenguajes de programación Fundamentos de Java
Arreglos unidimensionales
Un arreglo es un conjunto de variables del mismo tipo tratadas como una sola entidad.; a
cada variable dentro de un arreglo se le llama elemento de arreglo. Un arreglo es útil cuando no
deseamos nombrar individualmente a un grupo considerable de variables u objetos similares. En
Java, los arreglos son en realidad objetos y deben declararse e instanciarse de la siguiente forma:
tipo [] identificadordearreglo;
identificadordearreglo = new tipo [tamaño];
O también:
En donde:
• tipo será el tipo de datos que el arreglo contendrá; podrán usarse tanto tipos
primitivos como tipos objeto (String por ejemplo).
• [] serán los corchetes que indican al compilador que se está declarando un arreglo
y podrán ir también después del identificadordearreglo.
• identificadordearreglo será el nombre que le daremos a nuestro arreglo
• tamaño será el número de elementos que nuestro arreglo habrá de contener. Podrá
ser expresado en forma de variable o valor literal siempre y cuando sea entero, dado
que no existen las posiciones de arreglo de punto flotante. Si el arreglo es local a un
método, la variable deberá ser inicializada previamente.
60
Lenguajes de programación Fundamentos de Java
Ejemplos:
int i = 50;
String names[] = new String[i];
Para llenar los elementos de un arreglo después de crearlo, emplee la siguiente sintaxis:
identificadordearreglo[indice] = valor;
En donde:
Ejemplos:
ages[0] = 19;
ages[1] = 20 + 12;
ages[2] = a + b;
ages[3] = suma(1,2);
Para llenar los elementos de un arreglo cuando se instancia, emplee la siguiente sintaxis:
tipo [] identificadordearreglo = {valores_separados_por_coma};
En donde:
Ejemplos:
int [] ages = {19, 42 + 92, a + b};
NOTA: No es posible declarar e inicializar un arreglo en dos líneas ya que esto causaría un
error de compilación.
Por último (y como ya se ha podido dar cuenta) para acceder a los elementos individuales
de un arreglo de datos primitivos con la finalidad de obtener su valor o cambiarlo, basta con
enunciar el nombre del arreglo y especificar entre los corchetes el índice del elemento que
deseamos acceder, recordando siempre que a cada elemento N, le corresponde el índice N-1:
System.out.println(ages[4]);
Imprimirá en pantalla el valor del quinto elemento contenido en el arreglo ages. Por otro
lado, cuando el arreglo contiene objetos habrá que enunciar el nombre del arreglo y el índice del
elemento, seguido del operador punto y del nombre del atributo o método que se desea emplear;
por ejemplo:
System.out.println(shirts[0].shirtID);
Imprimirá en pantalla el valor del atributo shirtID del primer objeto del arreglo
shirts. Así mismo, la siguiente expresión:
shirts[0].displayShirtInformation();
El atributo length
Todos los objetos de tipo array cuentan con un atributo length que almacena de manera
automática el tamaño del arreglo. El largo de un arreglo es conocido formalmente como sus
límites. Como se explicó anteriormente, los límites de un arreglo de 10 elementos van de cero a
nueve, los de uno de 100 elementos van de cero a 99 y así sucesivamente, dado que el índice del
primer elemento siempre es cero. Contrario al lenguaje C, Java almacena en una variable
específica el tamaño del arreglo, y emplea a esta variable cada vez que se hace acceso al mismo.
Si el índice está fuera de sus límites se genera un error, lo cual asegura que no se invadan
posiciones de memoria no autorizadas.
Para obtener el atributo length de un objeto array dado, emplee la siguiente sintaxis:
identificadordearreglo.length
S 0
M 1
size L
L 2
0 shirtID
0.0 price
U colorCode
0x00099
0x179009 0x00327
0 shirtID
0.0 price
U colorCode
0x00990
63
Lenguajes de programación Fundamentos de Java
En este caso, el identificador almacena una referencia que apunta a otro objeto que a su vez
almacena referencias a otros tres objetos diferentes, todos ubicados en el heap.
Con este código, inicializaríamos un arreglo de enteros de 100 elementos con valores de
cero a noventa y nueve.
Cualquier programa en Java tratará lo que se escriba después del nombre de nuestro
programa como una cadena literal; cada palabra será tomada como un elemento del arreglo args
y será responsabilidad de nosotros extraer uno a uno esos valores y convertirlos al tipo de dato
que se requiera. Tomemos como ejemplo el siguiente código:
args[0] = Hi
args[1] = There
Ahora bien, ¿Qué pasa cuando esperamos usar los argumentos como cantidades numéricas?
Dado que cualquier número será tratado como una cadena, tendremos que convertir cada
elemento a su equivalente numérico. Java provee una clase asociada a cada tipo primitivo de dato
(Integer para los datos de tipo int, Byte para los de tipo byte, etc.) y cada una provee un
64
Lenguajes de programación Fundamentos de Java
método para realizar la conversión (con excepción de la clase Character). Estos métodos,
conocidos como métodos de parsing tienen la siguiente forma:
Nombredeclase.parseTipo(argumento);
Por razones obvias, cada método de conversión tiene un valor de retorno igual al tipo de la
clase a la que pertenecen. Por ejemplo, para convertir el primer argumento del arreglo args del
método main a un tipo int, podríamos hacer lo siguiente:
int ID = Integer.parseInt(args[0]);
Ejercicio 10
• Diseñe un programa que reciba desde el prompt del sistema un número entero y lo
convierta a binario, desplegando posteriormente el resultado en pantalla.
65
Lenguajes de programación Fundamentos de Java
Arreglos bidimensionales
Los arreglos en Java pueden ser multidimensionales (comúnmente llamados matrices). Un
arreglo de dos dimensiones será en realidad un arreglo de arreglos que puede visualizarse como
una tabla de varias filas y varias columnas.
O también:
tipo [][] identificadordearreglo = new tipo [filas][columnas];
En donde:
Ejemplo:
Para llenar los elementos del arreglo especifique el número de fila y el número de columna
en donde desea asignar el valor; por ejemplo, los enunciados:
matrix[0][0] = 1;
matrix[4][4] = 25;
66
Lenguajes de programación Fundamentos de Java
Ejercicio 11
• Diseñe un programa que construya una matriz de cuatro por cuatro y la inicialice
con valores del 1 al 16 de tal manera que quede como la siguiente tabla:
1 2 3 4
5 6 7 8
9 10 11 12
13 14 15 16
Antes: 10 10
Despues: 10 10
67
Lenguajes de programación Fundamentos de Java
Lo anterior comprueba entonces que los cambios que hagamos a las variables a y b dentro
del método method del objeto myTest no afectan en lo absoluto a las variables a y b del
método main, puesto que lo único que estamos haciendo es copiar el valor de las variables en los
argumentos del método; dichos parámetros se crean al invocar al método y se destruyen al salir
de él.
Con los objetos, sin embargo, la situación es completamente diferente, ya que el nombre de
un objeto es en realidad una referencia al mismo; por ello, cuando se pasa un objeto a un método
se dice que se está realizando un llamado por referencia. Como es de suponerse, los cambios que
realicemos en el objeto dentro del método, afectarán al objeto original, puesto que ahora el
argumento está haciendo referencia al mismo objeto.
Antes: 10 10
Despues: 20 20
En este caso, las acciones efectuadas a los miembros del objeto referenciado por ref
dentro del método method de la clase Test2 afectan a los miembros del objeto referenciado
por myTest2 dado que en realidad se trata de dos referencias diferentes que apuntan al mismo
objeto y por lo tanto a los mismos miembros.
68
Lenguajes de programación Fundamentos de Java
Como puede apreciarse, cada vez que se invoca al método method, se crea un nuevo
objeto de tipo Test3 con un incremento de diez a su atributo a. El valor de retorno es la
referencia al objeto creado, la cual se almacena en myTest3_2 permitiendo que el objeto no sea
recogido por el recolector de basura.
Implementación de herencia
La palabra reservada extends indica al compilador que una clase hereda atributos y
métodos de una superclase; la sintaxis para aplicarla es la siguiente:
[modificador] class identificadordeclase extends identificadordesuperclase
En donde:
Suponga que se cuenta con una superclase llamada Clothing que tiene la siguiente
forma:
69
Lenguajes de programación Fundamentos de Java
Como puede observarse, la clase Clothing contiene atributos y métodos que pueden ser
empleados por cualquier artículo de ropa; sin embargo, cada artículo podrá requerir de atributos y
métodos específicos según su clase. Una camisa, por ejemplo, podría tener códigos de color
específicos, en comparación con un zapato o un cinturón. A continuación se muestra un ejemplo
de la clase Shirt extendiendo a la clase Clothing y heredando todo de ella:
70
Lenguajes de programación Fundamentos de Java
NOTA: Observe con detenimiento que los atributos ID, description, price y
quantityInStock de la clase Clothing son privados; aunque Shirt los hereda de
su superclase no puede accederlos directamente dado que no los puede ver. Es por ello que
requiere emplear los métodos públicos get para desplegarlos. Dependerá estrictamente de
nuestras necesidades definir si los atributos de una superclase podrán o no ser manipulados
directamente por sus subclases.
Contrario a como se estila en otros lenguajes de programación, en Java una subclase sólo
podrá heredar de una superclase a la vez; lo anterior nos obliga a crear siempre una jerarquía de
herencia en donde una superclase podrá tener muchas subclases pero una subclase sólo podrá
tener una superclase.
Java provee mecanismos para limitar la herencia de una clase mediante el empleo de dos
modificadores:
• final: El cual impide que una clase sea heredada. Cuando una clase se cataloga
como final, será imposible extenderla o subclasificarla.
• abstract: El cual impide que una clase sea instanciada. Las clases abstractas se
consideran clases incompletas que aún no implementan ciertos métodos, por lo que
no podrán utilizarse para crear objetos.
Legalmente, una clase deberá declararse como abstracta cuando al menos uno de sus
métodos sea abstracto. La declaración de métodos abstractos se explica con detenimiento más
adelante.
Ejercicio 12
• Diseñe otra clase de artículo de ropa que herede todos los atributos y métodos de la
clase Clothing. Inclúyale al menos un atributo y un método únicos.
• Diseñe una clase de prueba que verifique a la clase Shirt y a la clase recién
creada. Emplee el método calculateID() para asignarles identificadores únicos
a los objetos de prueba.
71
Lenguajes de programación Fundamentos de Java
Ejemplo:
public class A{
public int i, j;
public void show(){
System.out.println(i + “ “ + j);
}
}
Lo mismo sucederá con los atributos: Cuando un atributo de una subclase se llame igual
que un atributo de su superclase, se considerará que este atributo se está sobrescribiendo. Por
ejemplo:
public class A{
int i;
}
Ejemplo:
class prueba{
final void finalMethod(){
System.out.println(“Este es un método final”);
}
}
72
Lenguajes de programación Fundamentos de Java
Métodos abstractos
Los métodos abstractos son aquellos que pertenecen a una determinada estructura de
herencia pero que requerirán de una implementación específica para cada subclase. Por esta razón
es que a los métodos abstractos se les conoce más comúnmente como métodos de
responsabilidad de subclase.
Dado que los métodos abstractos no tienen bloque principal, su implementación deberá
hacerse en cada una de las subclases que lo hereden. Tanto el nombre como los parámetros de los
métodos concretos de cada implementación deberán coincidir exactamente con lo estipulado por
el método abstracto.
Como se indicó con anterioridad, cualquier superclase con al menos un método abstracto se
considerará una clase abstracta y deberá ser declarada como tal. Recuerde además que una clase
abstracta no puede instanciarse.
Ejemplo:
74
Lenguajes de programación Fundamentos de Java
En este caso la situación cambia aún más. Dado que en este caso la superclase posee un
constructor, no existe un constructor por default, lo que nos obliga a invocar el constructor de la
superclase de manera manual mediante el enunciado que se encuentra en la línea 4 del código de
la clase SubClass.
super es una palabra clave que tiene dos formas generales. La primera nos permite
invocar el método constructor de nuestra superclase y tiene la siguiente forma:
super(argumentos);
Por supuesto, los argumentos deberán coincidir exactamente con los valores que los
constructores esperan (en caso de que se trate de más de uno). La invocación al constructor de la
superclase deberá ser obligatoriamente el primer enunciado en el constructor de la subclase y si
no se encuentra, se añade por omisión la invocación al constructor default de la superclase con la
sentencia super().
Aquí el compilador de Java nos está advirtiendo de la falta del constructor por default en la
superclase; ante esta situación tenemos dos opciones: la primera por obvias razones sería incluir
el constructor por omisión en la superclase como en el siguiente ejemplo:
Puesto que los constructores pueden sobrecargarse, es posible utilizar a super() con
cualquier serie de argumentos, según se especifique en la superclase.
76
Lenguajes de programación Fundamentos de Java
super.miembro
Donde miembro podrá ser ya sea un nombre de método o un atributo. Esta forma de super
es particularmente útil cuando los miembros de la subclase ocultan a los de la superclase debido a
la sobrescritura.
Ejemplo:
public class A{
int i;
}
public class B extends A{
int i;
B(int a, int b){
super.i = a;
i=b;
}
void show(){
System.out.println(“i de la superclase: “ + super.i);
System.out.println(“i de la subclase: “ + i);
}
}
Por ejemplo, todas las clases básicas de Java se encuentran incluidas en el paquete
java.lang (String, Math, Integer, etc.); de hecho hemos empleado varias de estas
clases a lo largo del manual. La razón por la cual hasta el momento no hemos tenido que hacer
ninguna referencia a este paquete, es porque todas las clases contenidas en java.lang se
consideran de manera implícita en nuestro código.
Sin embargo, cuando se desea emplear las clases provistas por los otros paquetes del API,
será necesario incluir un enunciado de importación en donde se detalle el nombre calificado
completo del paquete. A continuación, se mencionan los paquetes estándares de Java:
• java.net que contiene clases para ejecutar operaciones relacionadas con redes de
computadoras (como sockets y URLs).
• java.io que contiene clases para manejar archivos de disco y provee
herramientas para realizar tareas de escritura y lectura.
• java.util que contiene múltiples utilerías para realizar diversas tareas
(generación de números aleatorios, definir propiedades del sistema, etc.).
Para importar una clase se deberá colocar antes del nombre de la clase en donde queramos
realizar la importación un enunciado con la siguiente sintaxis:
import nombredelpaquete.nombredelaclase;
O también:
import nombredelpaquete.*;
Por ejemplo:
import java.util.Date;
import java.io.*;
Con el primer ejemplo se importa únicamente la clase específica que se desea emplear (para
este caso, la clase Date dentro del paquete java.util); este método es el preferido por los
programadores experimentados dado que reduce considerablemente el tiempo de compilación.
Con el segundo ejemplo se importan todas las clases del paquete java.io. Usar esta
forma sin embargo, tiene un inconveniente adicional: Cuando dos paquetes importados contienen
una clase con el mismo nombre, no se producirá ningún error en tiempo de compilación a menos
que hagamos referencia a la clase repetida. En este caso la única solución posible es importarla de
manera específica.
Una vez importado, podemos hacer referencia a cualquier clase del paquete, a sus atributos
o a sus métodos, como si estuvieran declarados en nuestro código. Por ejemplo:
import java.util.*;
En este caso, se importan todas las clases del paquete java.util. En particular, se
instancia un objeto de la clase Date empleando el constructor por default y referenciándolo con
el nombre myDate.
78
Lenguajes de programación Fundamentos de Java
NOTA IMPORTANTE: Cabe destacar que en ningún caso estamos agregando código a
nuestro programa; lo único que import nos permite es hacer referencia a clases y métodos
empleando solamente el nombre de la clase y el nombre del método (esto es, ahorrándonos
el trabajo de escribir el nombre calificado completo). Por lo anterior, es una sentencia que
provee únicamente comodidad al programador, pero en ningún caso es requerida.
Para una definición completa del API de Java, visite la siguiente liga:
https://docs.oracle.com/javase/7/docs/api/
Sabemos que un miembro public podrá ser accedido por cualquier objeto de nuestro
programa; esto se cumplirá aún cuando el objeto que desee hacerlo se encuentre fuera del paquete
de clases en donde el miembro reside. Un miembro private, por el contrario, sólo podrá ser
accedido por objetos de su misma clase.
79
Lenguajes de programación Fundamentos de Java
Existe tan sólo un nivel más de acceso para clases: el acceso por default. Al igual que
sucede con los miembros, una clase con acceso por default, podrá ser accedida únicamente por
las clases que se encuentran en su mismo paquete.
Como podrá suponerse, este nivel de acceso se obtiene cuando no incluimos el modificador
public antes de la palabra clave class en el encabezado de la clase.
80