You are on page 1of 24

UAA Sistemas Electrnicos

Programacin en Java

Eduardo Serna-Prez

Programacin orientada a objetos en Java

En la programacin estructurada es muy comn emplear las estructuras de datos como tipos de datos definidos por el usuario, y resultan muy tiles ya que a partir de ellas podemos definir un nuevo tipo de dato que podr estar compuesto de elementos de otro tipo y en algunos casos quizs de ms estructuras anidas o compuestas. Esto conlleva a un sin fin de posibilidades al momento de construir programas pues una estructura bien elaborada puede resolver ms de la mitad de un problema por no decir que en algunos casos hasta mas. Las funciones juegan un papel trascendental en la definicin de datos, ya que es posible construir funciones que manejen esos tipos de datos definidos por el usuario de manera local (empleando referencias), lo que puede aumentar y simplificar el diseo de programas ya que las funciones pueden estar asociadas a un tipo de dato en especial. Este es el concepto principal que engloba la idea de programacin orientada a objetos. En el paradigma Orientado a Objetos se dice que una Entidad u Objeto sta compuesto de al menos dos componentes fundamentales, por un lado los datos o atributos que caracterizan esa entidad y por el otro las funciones o mtodos que le permiten interactuar y comunicarse con el medio en el cual se desenvuelve. De manera que un objeto es una entidad concreta (instancia) de alguna clase que contiene propiedades e interacta con otros objetos.

Un programa orientado a objetos puede ser considerado como un conjunto de objetos que interactan entre si para obtener un resultado, al contrario de la programacin estructurada que solo cuenta con un conjunto de subrutinas aisladas de los datos.

3.1

Conceptos Bsicos

La Abstraccin de datos es un proceso que involucra la conceptualizacin de un problema identificando sus partes ms importantes y poniendo atencin en las similitudes y diferencias entre las entidades de un conjunto, para extraer las caractersticas esenciales que lo distingan y evitar las caractersticas no relevantes. Y as, se establece una sola representacin del concepto que tenga esas caractersticas pertinentes (clase). En programacin se puede ver a la abstraccin como la capacidad de crear nuevos tipos de datos que son definidos por el usuario extrayendo las propiedades esenciales de un concepto, sin preocuparse de los detalles exactos de la implementacin. Algunos simplemente lo definen como la capacidad de enfocarse en lo esencial.

UAA Sistemas Electrnicos

Programacin en Java

Eduardo Serna-Prez

3.2

Encapsulacin

Es el proceso mediante el cual tratamos de ocultar aquellos elementos de la implementacin de una clase que creemos que no deben de ser vistos por los usuarios del objeto, sin embrago por otro lado permitimos que una interfaz pblica pueda ser vista desde fuera del objeto para que el usuario la pueda acceder sin problemas. El ocultamiento y la visibilidad de los elementos de la clase es fundamental en el desarrollo de las mismas, pues los elementos contenidos en una entidad abstracta deben ser, preferentemente inaccesibles al usuario. Un diagrama de clases es un tipo de diagrama esttico que describe la estructura de un sistema mostrando su clases, atributos y las relaciones entre ellos. Los diagramas de clases son utilizados durante el proceso de anlisis y diseo de los sistemas, donde se crea el diseo conceptual de la informacin que se manejar en el sistema, y los componentes que se encargaran del funcionamiento y la relacin entre uno y otro. De manera que la encapsulacin es una forma simple de conceptualizar el ocultamiento de los atributos de una clase. Clase atributo1 : <tipo> + atributo2 : <tipo> ! + atributoN :<tipo> + metodo1(argumentos) : <tipo> metodo2(argumentos) : <tipo> ! + metodoN(argumentos) : <tipo> Podemos observar en la parte superior del diagrama la referencia al nombre de la clase que se esta construyendo, posteriormente podemos observar la definicin de las variables que van a ser empleadas dentro de la clase. Por ultimo se encuentran varios mtodos definidos en la parte inferior, estos mtodos pertenecen a la clase y sern empleados como medio de comunicacin entre procesos. 3.2.1 Modificadores de acceso Como hemos visto en el diagrama una clase esta compuesta por atributos (datos) y por mtodos (funciones), adems podemos observar a su izquierda un smbolo de mas (+) y menos (). Estos smbolos nos indican el nivel de acceso, es decir que esos elementos de la clase podrn o no ser vistos desde fuera de la clase. A continuacin veremos que existen varios niveles de acceso para variables y mtodos, cada uno de ellos ser empleado segn las necesidades de diseo y programacin: Los miembros (mtodos/atributos) public (pblicos) sern vistos desde cualquier punto fuera de la clase, es decir que puede ser usado o manipulado por cualquier otra clase (programa). Los miembros (mtodos/atributos) private (privados) estarn nicamente disponibles por los mtodos pertenecientes a la clase, es decir que nicamente sus mtodos hermanos pueden accederlos. Existen adems los modificadores de acceso protegido (protected) y por defecto (default), pero esos sern explicados posteriormente.

UAA Sistemas Electrnicos

Programacin en Java

Eduardo Serna-Prez

3.2.2 Declaracin e implementacin Los mtodos y atributos declarados como public son frecuentemente reconocidos como la interfase del objeto debido a que son los nicos elementos que pueden comunicarse con otros objetos. Los detalles de cmo un mtodo completa una operacin es llamado implementacin del mtodo. Uno de los principales objetivos en la programacin orientada a objetos es crear mtodos pblicos que puedan manipular a los atributos a travs de una correcta implementacin que no interfiera con la interfase de comunicacin. Por lo general se recomienda que los atributos sean privados, pues esto asegura una consistencia en el manejo de los mismos, ya que no permitiremos que tomen valores que puedan poner en riesgo el buen funcionamiento del conjunto (clase). Se recomienda construir el nmero necesario de mtodos pblicos que nos permitan manipular a los atributos. Tambin es posible que algunos mtodos deban ser catalogados como privados, pero eso es a criterio del diseador de la clase. En su momento hablaremos de los accessors (getters / setters), mtodos que son los responsables de manipular aquellos atributos que consideramos como atributos privados de la clase los cuales no deben de ser manipulados directamente.

3.3

Definicin de clase

La programacin orientada a objetos se puede definir como una tcnica o estilo de programacin que utiliza las clases como bloque esencial de construccin. Las clases son en realidad un tipo de datos abstracto, que engloba a los atributos y a las operaciones asociadas con esos atributos. Cada vez que se construye un objeto de una clase, se crea una instancia de esa clase. En general, los trminos objetos e instancias de una clase se pueden utilizar indistintamente. 3.3.1 Declaracin de clase Para el diseo de las clases emplearemos la palabra clave class y especificamos el nombre de la clase, posteriormente declaramos los atributos y mtodos dentro del bloque de la clase. Adicionalmente por el momento emplearemos dos modificadores que nos indicaran el tipo de acceso a los miembros de la clase, public y private. [public] class NombreClase { /* definicin de variables miembro */ [<public><private><protected>] <tipo> lista_de_atributos; /* declaracin e implementacin de constructores */ NombreClase( [lista_de_argumentos] ){ <tipo> lista_de_variables; lista_de_sentencias; ... } /* declaracin e implementacin de mtodos */ [<public><private><protected>] <tipo> metodo([lista_de_argumentos]){ <tipo> lista_de_variables; lista_de_sentencias; ... } }

UAA Sistemas Electrnicos

Programacin en Java

Eduardo Serna-Prez

La palabra public nos indica que la clase ser vista desde cualquier punto, la ausencia del identificador de acceso indica que la clase nicamente ser vista desde un grupo selecto llamado paquete. Todos los componentes de la clase, es decir, los atributos y mtodos deben ser definidos dentro del bloque { ! } de la clase. Es importante recordar que todas las variables y funciones en Java deben pertenecer a alguna clase (ciudadanos de primer orden), ya que no existen variables y funciones globales. Declaracin de atributos Los atributos miembros declarados dentro de la clase como ya hemos visto son variables de una clase particular de objeto y representan las propiedades o caractersticas ms bsicas de ese objeto en particular. Las variables miembro o variables de instancia pueden ser declaraciones de cualquier tipo de dato existente en Java, incluyendo objetos de cualquier otra clase que este disponible dentro o fuera del paquete, de tal forma que los atributos miembros de la clase tendrn modificador de acceso (public, private o default) que le permitirn determinar el tipo de acceso al que esta disponible. Los atributos miembro suelen ser declarados en la parte inicial de la clase justo antes de la declaracin de mtodos miembro, as pues, los datos miembro estarn disponibles de manera local a todas las funciones de la clase por lo que no es necesario hacer referencia explicita a ellos, aunque en caso de que sea muy necesario (resolucin de ambigedad), se emplea el identificador this para reforzar la referencia. class A { private int a, b, c; // a, b y c son enteras y privadas public String nombre, apellido; // variables publicas double arreglo[], valor; // variables por defecto } Los atributos de la clase solo sern declarados, hasta este punto no es necesario realizar una inicializacin de los datos ya que esta tarea la realizara el constructor de la clase. Declaracin de mtodos La comunicacin con un objeto se realiza a travs del paso de mensajes (mtodos). El paso de mensajes es el trmino utilizado para referirnos a la invocacin o llamada de una funcin miembro de un objeto. Los mtodos miembro de la clase son todas aquellas funciones o mtodos que estn relacionadas con un objeto en particular, es decir, son las acciones que puede realizar un objeto de cierta clase. En un archivo de programa java es posible definir varias clases, pero no puede haber ms de una clase publica. En caso de definir una clase pblica el archivo debe tener exactamente el mismo nombre de la clase pblica, con la extensin .java, por lo que el siguiente cdigo estar presente en un archivo llamado Ejecuta.java.
import java.lang.*; // importa a las clases bsicas del lenguaje public class Ejecuta { // clase ejecutora de la aplicacin public static void main( String[] args ) { Ejemplo e = new Ejemplo(); // crea un objeto de clase Ejemplo e.iniciar( 1, 3, 6 ); // invoca al mtodo inicia e.verDatos(); // invoca al mtodo verDatos System.out.println( "Suma " + e.sumaDatos() ); } }

UAA Sistemas Electrnicos

Programacin en Java

Eduardo Serna-Prez

class Ejemplo { private int dato1, dato2, dato3; // datos miembro public void iniciar( int a, int b, int c ) { // mtodo iniciar this.dato1 = a; this.dato2 = b; this.dato3 = c; } public void verDatos() { // mtodo verDatos String salida = "dato1 "+dato1+" dato2 " +dato2+" dato3 "+dato3; System.out.println(salida); } public int sumaDatos() { // mtodo sumaDatos return (dato1 + dato2 + dato3); } }

Como podemos observar todos aquellos atributos y mtodos que forman parte de una determinada clase; y que representan sus caractersticas y propiedades particulares, encapsulan estos elementos y los dota de ciertos criterios de visibilidad y manipulacin con respecto a otras clases. Adems la clase Ejemplo es declarada en la parte superior y posteriormente es declarada una clase publica Ejecuta, que es la clase principal que se encargara de la ejecucin del programa, pues implementa el mtodo main que es el responsable de iniciar la ejecucin completa del programa (punto de arranque). Entonces la clase Ejecuta crea una instancia (objeto) de la clase Ejemplo a travs del operador new reservando espacio para un objeto llamado e de tipo Ejemplo. La clase Ejecuta es la responsable de iniciar el proceso de ejecucin pues es una clase publica que contiene al procedimiento main, de esta manera la clase Ejemplo, contiene todos los elementos de programacin necesarios para ejecutar diversas acciones, as como un conjunto de datos (propiedades) sobre los cuales realiza ciertas operaciones. Tambin es posible ver este ejemplo desde otra perspectiva en la cual no existe una clase principal que funja las acciones de una directora de orquesta, es decir la responsable de la ejecucin del programa, de manera que es posible dentro de la misma clase incrustar la funcin main que sea la responsable de la direccin del programa. De manera que solo existir una sola clase que es la encargada de realizar todas las acciones. Es importante recordar que ambos programas realizan las mismas acciones, salvo que se tienen sus elementos distribuidos de una manera distinta, pero en esencia el resultado es el mismo.
import java.lang.*; // Ejemplo.java public class Ejemplo { private int atributo1, atributo2, atributo3; public void iniciar( int a, int b, int c ) { // mtodo iniciar this.atributo1 = a; this.atributo2 = b; this.atributo3 = c; } public void verDatos() { String salida = "dato 1 " + this.atributo1 + "\n dato 2 " + this.atributo2 + " dato 3 " + this.atributo3; System.out.println(salida); }

UAA Sistemas Electrnicos

Programacin en Java

Eduardo Serna-Prez

public int sumarDatos() { return (atributo1 + atributo2 + atributo3); } public static void main(String[] args) { Ejemplo c = new Ejemplo(); e.iniciar( 1, 3, 6 ); // invoca al mtodo inicia c.verDatos(); System.out.println("Suma " + e.sumarDatos()); } }

Note que la clase Ejemplo crea un objeto de la misma clase empleando el operador new, de manera que manda a llamar al constructor por defecto de la clase, el constructor de la clase Ejemplo no se encuentra presente de forma especifica, ya que el compilador lo introduce. Si en algn momento el constructor fuera re-implementado, ser necesario incrustar el constructor por defecto de manera especifica, si es el caso de que sea necesario en la ejecucin.

3.4

Acceso a miembros de una clase

El acceso a los datos miembro y a las funciones miembro se realiza a travs del operador ., de manera que cualquier funcin miembro de la clase que sea publica, podr ser ejecutada desde fuere de ella empleando el operador de acceso a miembro. Para el caso de una funcin miembro que ejecute a una funcin hermana, es decir, una funcin que se encuentra a su mismo nivel de programacin, podr ser ejecutada directamente como si se tratara de una funcin local. Las variables o propiedades de la clase tambin pueden ser accedidas de igual manera con el operador ., aunque esta clase de acceso se determina en base a su nivel de alcance, es decir si se trata de datos pblicos o privados. Es recomendable tener niveles de acceso en los datos y funciones ya que esto conlleva a un buen diseo de la clase que pretendamos implementar. Ejemplo c = new Ejemplo(); e.iniciar( 1, 3, 6 ); // invoca al mtodo inicia c.verDatos(); System.out.println("Suma " + e.sumarDatos());

3.5

Constructores

Los constructores son las funciones mimbro que llevan el mismo nombre que la clase, en realidad son las funciones que se ejecutan primero cuando se declara un objeto de una determinada clase. El constructor es responsable de proveer de toda la infraestructura necesaria para que un objeto pueda trabajar, por ejemplo, inicializa las variables a un valor dado, crea e inicializa las estructuras dinmicas en tiempo de ejecucin.
import java.util.Scanner; public class Main { public static void main(String [] args) { Empleado empl1, empl2; // declaracin de objetos empl1= new Empleado(33,"Ana", 1250.00); //inicializa objetos Scanner s = new Scanner(System.in); System.out.print("clave "); int clave = s.nextInt();

UAA Sistemas Electrnicos

Programacin en Java

Eduardo Serna-Prez

System.out.print("nombre "); String nombre = s.next(); System.out.print("salario "); double salario = s.nextFloat(); empl2 = new Empleado(clave, nombre, salario); System.out.println("Los datos de uno "); empl1.mostrar(); System.out.println("Los datos de dos "); empl2.mostrar(); s.close(); } } class Empleado private private private { int clave; String nombre; double salario;

public Empleado(int clave, String nombre, double salario) { this.clave = clave; this.nombre = nombre; this.salario = salario; } public void mostrar() { System.out.println("clave "+ clave + " nombre " + nombre + " salario "+ salario); } }

3.5.1 Sobrecarga de constructores Los constructores pueden o no llevar argumentos, y en ningn caso regresan valor alguno, su nivel de acceso es siempre publico, pues es necesario que se ejecuten desde fuera de la clase cuando se crea una instancia de una clase. Cuando un constructor no lleva argumentos se le suele llamar constructor por default o por defecto. En muchos casos un solo constructor no ser suficiente para describir el comportamiento completo de nuestro objeto por lo que ser necesario sobrecargarlo, es decir emplear en varias definiciones de funcin el mismo nombre de la funcin constructora, cuidando que difieran el numero y tipo de argumentos en cada funcin. A continuacin presentamos un ejemplo que describa el comportamiento de los nmeros complejos, para ello crearemos una clase a la que llamaremos complejo. La clase complejo cuenta al menos con dos miembros privados, un nmero flotante que representa la parte real del nmero complejo, y un nmero flotante que represente la parte imaginaria del nmero:
class Complejo { private double real, imag; // variables miembro public Complejo() { } // constructor por defecto public Complejo(double real, double imag) { // con argumentos this.real = real; // inicializa el valor de las variables this.imag = imag; } public Complejo( Complejo x ) { // constructor de copia this.real = x.real; this.imag = x.imag; }

UAA Sistemas Electrnicos

Programacin en Java

Eduardo Serna-Prez

public void imprimir() { // mostrara el contenido String out = out = real+(imag > 0 ? "+":"-")+imag + "i\n"; System.out.println(out); return; } }

En el ejemplo creamos 3 funciones constructoras que se encargan de inicializar los valores de la clase complejo. El constructor sin argumentos inicializa el valor de las variables a cero, de manera que estn disponibles para su uso. El constructor con argumentos recibe un par de valores que son en realidad los elementos bsicos de la clase complejo, es decir los nmeros que presumiblemente sern representados como tal; parte real y parte imaginaria. Observe como ambos argumentos son recibidos por la funcin constructora y son manipulados de manera local por la funcin, tome en cuanta que ambas variables tienen el mismo nombre (las de argumento y las locales a la clase) por lo que es necesario diferenciar entre ellas empleando el operador this. El operador this le indica que las variables a las que se refiere son a las del objeto (propietario de la llamada). Finalmente un constructor de copia, es capas de construir un objeto a partir de otro objeto de la misma clase. En ocasiones es til disear constructores de copia pues es posible que se tenga la necesidad de tener una copia fiel de algn objeto para que posteriormente sea manipulado. Hay 3 razones por las que se debe de sobrecargar las funciones constructoras: Ganar flexibilidad Permitir arreglos dinmicos Construir copias de objetos. As pues la declaracin para objetos de la clase complejo se realizara de la siguiente manera:
public class TestComplejo { public static void main(String [] arg) { Complejo x = new Complejo(); Complejo y = new Complejo(1.1,2.2); Complejo r = new Complejo( x ); x.imprimir(); y.imprimir(); r.imprimir(); } }

3.6

Creacin y uso de objetos

Todos los objetos en java son referencias y como tales, es indispensable crearles un espacio de datos en memoria, para ello se emplea el operador new, que es el responsable de llamar al constructor de la clase y crearle un espacio de datos. Para el caso de una clase cualquiera se contara con varias versiones de constructores, finalmente el operador new realizara la misma accin, reservar un bloque de memoria dentro del montculo de memoria (memory heap) de manera que se creara una referencia a la cual estarn asociados las variables de instancia. Recuerde que todas las variables declaradas dentro de los mtodos son consideradas para ser declaradas dentro de la pila de memoria. Podemos observar en la figura que en la memoria de pila (memory stack), se encuentran todas aquellas variables que hayan sido declaradas dentro de un mtodo (variables locales), incluyendo

UAA Sistemas Electrnicos

Programacin en Java

Eduardo Serna-Prez

a los tipos de datos compuestos como los arreglos y objetos, solo que aquellos considerados como objetos (arreglos e instancias) almacenan una direccin de memoria (un puntero que resulta transparente para el programador). De manera que es muy importante recordar que TODO objeto es una referencia de memoria dinmica que reserva espacio suficiente para las variables de instancia.

3.6.1 Declaracin e inicializacin de referencias Ahora veamos otro ejemplo donde podemos aplicar la definicin de un constructor, por ejemplo, suponga que se requiere un programa donde almacenemos la informacin relacionada con algn empleado, con datos bsicos como nombre del empleado y numero de identificacin:
class Empleado { public int clave; public String nombre; public double salario; public Empleado() {} public Empleado(int clave, String nombre, double salario) { this.clave = clave; this.nombre = nombre; this.salario = salario; } public void mostrar() { System.out.println("clave "+ clave + " nombre " + nombre + " salario "+ salario); }

UAA Sistemas Electrnicos

Programacin en Java

Eduardo Serna-Prez

El primero constructor se encargara de inicializar los valores, mientras que el segundo se encargara de construir elementos de ste tipo a partir de datos independientes. Ahora la forma de interactuar con esta clase es declarando algunos objetos o referencias de la clase e inicializarlos con el operador new, de manera que se llame al constructor de la clase quien se encargara de asignar el espacio necesario en memoria para los datos.
import java.util.Scanner; public class Main { public static void main(String [] args) { Empleado [] vector; // vector de objetos System.out.print("cuantos registros ?"); Scanner s = new Scanner(System.in); int n = s.nextInt(); vector = new Empleado [n]; for (int i = 0; i < vector.length; i++) { vector[i] = new Empleado(); System.out.print("clave "); vector[i].clave = s.nextInt(); System.out.print("nombre "); vector[i].nombre = s.next(); System.out.print("salario "); vector[i].salario = s.nextFloat(); } for (int i = 0; i < vector.length; i++) vector[i].mostrar(); s.close(); } }

El arreglo que se genera es un arreglo de referencias de manera que al momento de construirlo solo se tiene un arreglo que esta inicializado con valores de null en cada casilla, por ello es necesario mandar llamar al constructor para cada casilla.

3.7

Sobrecarga de mtodos

Cuando dos o mas mtodos comparten el mismo nombre y en tanto difieran en el tipo y/o nmero de argumentos, y preferiblemente cada una de ellas contenga un cdigo diferente, se dice que estn sobrecargadas (overloaded). De manera que para obtener la sobrecarga de funciones simplemente hay que declarar y definir todas las versiones requeridas de la funcin. A continuacin mostramos un ejemplo donde emplearemos la sobrecarga de funciones. La primer funcin sobrecargada es Abs (que obtiene el absoluto de un nmero), en este caso especificamos que una de ellas recibir como argumento un valor entero y otra un valor doble. El compilador se har cargo de interpretar el argumento y decidir que funcin se har cargo de l.
class A { public static void main(String [] x){ System.out.println(Sobrecarga.maximo(1,2)); int [] a = {1,3,2}; System.out.println(Sobrecarga.maximo(a)); Sobrecarga obj = new Sobrecarga(); System.out.println(obj.abs(-1)); System.out.println(obj.abs(-23F)); } }

10

UAA Sistemas Electrnicos

Programacin en Java

Eduardo Serna-Prez

public class Sobrecarga { public int abs(int x) { return x > 0 ? x : x*-1; } public float abs(float x) { return x > 0 ? x : x*-1; } public static int maximo(int x, int y){ return x > y ? x : y; } public static int maximo( int [] array){ int n = array[0]; for( int i = 1; i < array.length; i++) n = n > array[i] ? n : array[i]; return n; } }

Tambin definimos dos funciones maximo (mayor elemento de) que regresaran como valor el elemento mayor, ya sea de dos nmeros enteros o de una lista de nmeros (array). La sobrecarga es un mecanismo computacional muy poderoso, pues permite una mayor expresividad al momento de definir un programa.

3.8

Manejo de objetos

Ahora que ya hemos visto los elementos mas importantes involucrados en la construccin de programas en Java, veremos la forma en como poder disear un programa fcilmente y que involucre un esquema orientado a objetos. Para ello plantearemos un problema simple, se pretende construir un programa que sea capas de administrar los datos de un grupo de estudiantes, los datos y la relacin existente entre ellos se muestra a continuacin en un diagrama:

Manejo_alumno Alumno - id : int - nombre : String - apellido : String - faltas : int - promedio : float - materias : Materia [ ] - grupo : Alumno [ ] + capturar : void + mostrar : void + ordenar : void Manejo_materia Materia - nombre : String - creditos : int - calificacion : float - faltas : int - materias : Materia [ ] + capturar : void + mostrar : void

Del diagrama podemos inferir varias cosas, requerimos al menos 4 clases, una que defina los datos relacionados con un Alumno, otra para definir los datos de una Materia, adems podemos

11

UAA Sistemas Electrnicos

Programacin en Java

Eduardo Serna-Prez

observar que un Alumno requiere un conjunto de materias, adems podemos ver que es necesario contar con un par de clases que se encarguen de recabar la informacin necesaria de cada alumno y materia, de manera que es necesario contar con un par de clases que se hagan cargo de la manipulacin. Generalmente una clase esta compuesta por un conjunto de atributos los cuales debern de ser manipuladas de alguna forma, debido a que los atributos de la clase generalmente se declaran como privadas y sin por tanto inaccesibles, es necesario que exista un mecanismo que nos permita su fcil manipualicin. 3.8.1 Accessors

Antes de continuar con el desarrollo del problema de alumnos y materias es necesario definir el concepto denominado accessors, estos se definen como los mtodos que son capaces de interactuar con los atributos privados de una clase, debido a que los atributos son valores inaccesibles, entonces es necesario contar con mecanismos que interacten con ellos y se preserve la encapsulacin. A continuacin se define una clase A con un par de atributos dato1 de tipo int y dato2 de tipo String, ambos atributos tendrn sus respectivos mtodos get y set que se encargaran de interactuar de manera publica: class A {
private int dato1; private String dato2; public void setDato1(int dato1) { this.dato1 = dato1; } public int getDato1() { return dato1; } public void setDato2(String dato2) { this.dato2 = dato2; } public String getDato2() { return dato2; } }

Los mtodos setAtributo() se encargan de recolectar los datos relativos al atributo en cuestin, as como los mtodos getAtributo() se encargan de recuperar los valores relativos a cierto atributo. Una vez aclarado el concepto de los mtodos de acceso, prosigamos con el planteamiento relativo al problema de los alumnos y las materias. Para ello se plantea recolectar la informacin necesaria para un alumno, as como para el conjunto de materias que cursa, en este caso el alumno adems de sus datos cuenta con un arreglo de materias donde almacenar la informacin relativa a cada materia que cursa, para este caso se consideran 4 materias an que el modelo se presta para que sea un numero variable empleando listas ligadas. De momento conservaremos esta idea con arreglos para poder comenzar a modelarlo. La lista de cada mtodo getter y setter correspondiente a cada atributo de la clase Alumno, as como para la clase Materia se muestra a continuacin:
public class Alumno { private int id; private String nombre, apellido; private int faltas; private double promedio;

12

UAA Sistemas Electrnicos

Programacin en Java

Eduardo Serna-Prez

private Materia [] materias; public Alumno() { materias = new Materia [4]; } public Alumno(int promedio) { this.id = id; this.nombre = this.apellido this.faltas = this.promedio this.materias } id, String nombre, String apellido, int faltas, double nombre; = apellido; faltas; = promedio; = new Materia [4];

public String getApellido() { return apellido; } public void setApellido(String apellido) { this.apellido = apellido; } public int getFaltas() { return faltas; } public void setFaltas(int faltas) { this.faltas = faltas; } public int getId() { return id; } public void setId(int id) { this.id = id; } public String getNombre() { return nombre; } public void setNombre(String nombre) { this.nombre = nombre; } public double getPromedio() { return promedio; } public void setPromedio(double promedio) { this.promedio = promedio; } public Materia[] getMaterias() { return materias; } public void setMaterias(Materia[] materias) { this.materias = materias; }

13

UAA Sistemas Electrnicos

Programacin en Java

Eduardo Serna-Prez

Las materias estn organizadas de la siguiente manera: se cuenta con el nombre, el nmero de crditos, la calificacin y el nmero de faltas, observe la declaracin de cada getter y setter segn el atributo que le corresponda.
public class Materia { private String nombre; private int creditos; private double calif; private int faltas; public Materia() { } public Materia(String nombre, int creditos, double calif, int faltas) { this.nombre = nombre; this.creditos = creditos; this.calif = calif; this.faltas = faltas; } public double getCalif() { return calif; } public void setCalif(double calif) { this.calif = calif; } public int getCreditos() { return creditos; } public void setCreditos(int creditos) { this.creditos = creditos; } public int getFaltas() { return faltas; } public void setFaltas(int faltas) { this.faltas = faltas; } public String getNombre() { return nombre; } public void setNombre(String nombre) { this.nombre = nombre; } }

Una vez desarrolladas las clases responsables de la recoleccin de los datos, procedemos a crear las clases que se encargaran de recolectar la informacin relativa a esos datos, en primer lugar generaremos la clase Maneja_alumnos responsable de interactuar con el usuario final pues realizar los procesos de captura y despliegue de alumnos, para ello genera un arreglo que se asocia a un elemento llamado grupo. Suponemos que un grupo es una coleccin homognea de individuos de all el uso del arreglo. Se supone que al constructor le indicaremos el numero de alumnos asociados a un grupo.

14

UAA Sistemas Electrnicos

Programacin en Java

Eduardo Serna-Prez

import java.util.Scanner; public class Manejo_alumnos { private Alumno [] grupo; public Manejo_alumnos(int total) { // total asigna el numero de alumnos grupo = new Alumno [total]; } public void capturar() { // recaba la informacin de cada alumno for (int i=0; i < grupo.length; i++) grupo[i] = alumno(); } /* recolecta de manera individual cada alumno, es la responsable de interactuar con el usuario final desde la consola */ private Alumno alumno(){ Scanner cin = new Scanner(System.in); Alumno al = new Alumno(); System.out.print("ID ?"); al.setId(cin.nextInt()); System.out.print("Nombre ?"); cin.skip("\\s*\\n"); al.setNombre(cin.nextLine()); System.out.print("Apellido ?"); al.setApellido(cin.nextLine()); /* crea un objeto de tipo Manejo_materias, debido a que recabamos la informacin relativa a cada materia, capturar de materia regresa un arreglo de materias que es fcilmente manipulado */ Manejo_materias x = new Manejo_materias(); al.setMaterias( x.capturar() ); System.out.print("Promedio ?"); al.setPromedio( calculaProm( al.getMaterias() ) ); System.out.print("Faltas ?"); al.setFaltas(calculaFal( al.getMaterias() )) ; return al; } private double calculaProm(Materia[] x){ // double prom = 0; for(int i = 0; i < x.length; i++) prom += x[i].getCalif(); return prom/x.length; } calculamos el promedio

private int calculaFal(Materia[] x){ // contabilizamos las faltas int sum = 0; for(int i = 0; i < x.length; i++) sum += x[i].getFaltas(); return sum; } public void mostrar() { System.out.println("Id \t Nombre \t Apellido \t Promedio \t Faltas"); for(int i = 0; i < grupo.length; i++) { System.out.println( alumno(grupo[i]) ); } } private String alumno( Alumno x){ return x.getId() + "\t" + x.getNombre() + "\t" + x.getApellido() + "\t" + x.getPromedio() + "\t" + x.getFaltas(); }

15

UAA Sistemas Electrnicos

Programacin en Java

Eduardo Serna-Prez

/* ordenamos el arreglo en base a dos criterios diferentes, primero aparecern los alumnos con mayor promedio y que adems tengan el menor numero de faltas, debido a que manejamos un par de restricciones implementamos un sencillo mecanismo de ordenacin contemplando cada caso. Recuerde que aqu manejamos referencias de manera que el ordenamiento en si provocar una reasignacin de referencias */ public void ordenar() { for (int i = 0; i < grupo.length-1; i++) for(int j = i+1; j < grupo.length; j++) { if(grupo[i].getPromedio() < grupo[j].getPromedio()){ Alumno aux = new Alumno(); aux = grupo[i]; grupo[i] = grupo[j]; grupo[j] = aux; } if(grupo[i].getPromedio() == grupo[j].getPromedio() && grupo[i].getFaltas() >= grupo[j].getFaltas()){ Alumno aux = new Alumno(); aux = grupo[i]; grupo[i] = grupo[j]; grupo[j] = aux; } } } }

La reasignacin de referencias tiene un efecto transparente al usuario, pues al recorrer el arreglo el resultado es exactamente el mismo que corresponde a su ndice. La clase Manejo_materias realiza un proceso similar al de la clase Manejo_alumno, recolecta la informacin y manda la referencia de regreso a la clase Manejo_alumno.
import java.util.Scanner; public class Manejo_materias { Materia [] materias; public Manejo_materias() { this.materias = new Materia[4]; } public Materia [] capturar(){ for(int i = 0; i < materias.length; i++){ materias[i] = materia(); } return materias; } private Materia materia(){ Materia x = new Materia(); Scanner cin = new Scanner(System.in); System.out.print("Nombre ? "); x.setNombre(cin.nextLine()); System.out.print("Creditos ? "); x.setCreditos(cin.nextInt()); System.out.print("Calificacion ? "); x.setCalif(cin.nextDouble()); System.out.print("faltas ? "); x.setFaltas(cin.nextInt()); return x; } }

16

UAA Sistemas Electrnicos

Programacin en Java

Eduardo Serna-Prez

Finalmente echamos a volar todo el mecanismo creando un objeto de la clase Manejo_alumnos indicndole al constructor el numero de alumnos que pretendemos manejar, una vez establecido este valor mandamos a ejecutar al proceso de capturar que es el responsable de reaizar el alta de los alumnos y sus materias, tome en cuenta que al capturar la informacin de las materias se generara un calculo automtico para el promedio y el numero de faltas total.
public class Main { public static void main(String[] args) { Manejo_alumnos x = new Manejo_alumnos(3); x.capturar(); x.mostrar(); x.ordenar(); x.mostrar(); } }

La idea principal en este ejemplo es mostrar la forma en como se realiza la programacin orientada a objetos para problemas cotidianos, aqu tratamos de usar al mximo el concepto de orientacin a objetos ya que se construyen objetos de clases que interactan entre s transmitiendo mensajes de un objeto a otro.

3.9

Construccin y acceso de paquetes

Un paquete es una forma de organizar las diversas clases que conforman a nuestro proyecto en directorios bien definidos de manera que podamos tambin aclarar la existencia del nivel de acceso por default (sin nivel de acceso), que nos indica que un atributo o mtodo ser accesazo de manera local al los objetos de vecindario (directorio). Nuestra aplicacin esta construida dentro del directorio llamado paquete: Home/paquete datos/ Main.java
/* Main.java * importamos las clases del paquete datos para que estn presentes */ import datos.*; public class Main { public static void main (String [] args) { A obj = new A(); obj.porDefecto = 1; // error valor accesible unicamente por paquete obj.publico = 2; // accedido desde cualquier lado obj.privado = 3; // error valor accesible unicamente por la clase B obj2 = new B(); obj2.metodo(); } }

Dentro del directorio de datos se encuentran las clases A y B: Home/paquete/datos


/* A.java * la sentencia packaged indica que la clase A habitara en el vecindario de datos (directorio)*/ package datos;

17

UAA Sistemas Electrnicos

Programacin en Java

Eduardo Serna-Prez

public class A { int porDefecto; // ser accesible por el paquete datos public int publico; private int privado; // ser manipulado por objetos de la clase A } /* B.java * la sentencia packaged indica que la clase B habitara en el vecindario de datos (directorio)*/ package datos; public class B { A obj; public void metodo() { A obj = new A(); obj.porDefecto = 4; // es accesible pues viven en el mismo paquete obj.publico = 5; obj.privado = 6; // error variable solo accesible desde objetos de A } }

Podemos concluir entonces que los elementos declarados de tipo default (sin nivel de acceso) nicamente sern visibles dentro del directorio o paquete donde fueron declarados.

3.10 Variables y mtodos estticos


Cada objeto de una clase tiene su propia copia de todos los datos miembros de la clase. En ciertos casos es deseable que todos los objetos de una clase compartan una sola copia de una variable en especial. Por esta razn se utilizan las variables de tipo static, que presentan informacin a nivel de clase. A continuacin mostraremos un ejemplo de su declaracin y uso, suponga que se requiere una clase Nave, que ser la responsable de crear tantos objetos tipo Nave como sea necesario para un juego de video. De tal manera que ser necesario tener una variable que sea la responsable de llevar el conteo del numero total de naves existentes, de tal manera que al momento de que sean destruidas se decrementa el numero de naves a seran visualizadas.
class Nave { private private private private

int x,y; // coordenadas String nombre; // nombre de la nave int serie; static int count = 0; // variable de clase

Nave() { serie = count++; nombre = "Nave" + this.serie; } Nave(int x, int y) { this.x = x; this.y = y; this.serie = count++; nombre = "Nave" + this.serie; } public String getNombre(){

18

UAA Sistemas Electrnicos

Programacin en Java

Eduardo Serna-Prez

return nombre; } public static int getCount() { return count; } public String cuadrante() { return "("+x+","+y+")"; } protected void finalize() { count--; System.out.println("destruyendo"); } public String toString(){ return " Nombre "+ this.nombre + " Cuadrante "+ this.cuadrante(); } }

An cuando los datos miembro static parezcan variables globales, estos tienen alcance de clase. Los miembros static pueden existir aun si no se tienen ningn objeto de la clase, el acceso a estos miembros debe ser a travs de la clase misma, NombreClase.datoEstatico.
public class NaveApp { public static void main(String args[]) { Nave n1 = new Nave(2,3); System.out.println(n1.toString()); Nave n2 = new Nave(10,20); System.out.println(n2.toString()); System.out.println(Nave.getCount()); n1 = null; System.out.println("despues"); System.gc(); System.runFinalization(); System.out.println(Nave.getCount()); } }

Tambin es posible crear funciones static, que resultan muy utiles cuando se trata de usarlar para una tarea especifica donde no se vean involucrados los miembros del objeto, a estos mtodos se les conoce como mtodos de clase y se referencian de la misma forma que las variables static, NombreClase.metodoEstatico.
class OperaMat { private double [][] matrizA, matrizB; public double[][] getMatrizA() { return matrizA; } public void setMatrizA(double[][] matrizA) { this.matrizA = matrizA; } public double[][] getMatrizB() { return matrizB;

19

UAA Sistemas Electrnicos

Programacin en Java

Eduardo Serna-Prez

} public void setMatrizB(double[][] matrizB) { this.matrizB = matrizB; } public static double [][] capturar(){ Scanner in = new Scanner(System.in); int fils = 0, cols = 0; System.out.println("filas columnas"); fils = in.nextInt(); cols = in.nextInt(); double [][] tem = new double [fils][cols]; for(int f = 0; f < tem.length; f++) for(int c = 0; c < tem[0].length; c++) { System.out.print("elemento "); tem[f][c] =in.nextDouble(); } return tem; } public static void mostrar(double [][] tem){ for(int f = 0; f < tem.length; f++) { for(int c = 0; c < tem[0].length; c++) System.out.print(" " + tem[f][c]); System.out.println(); } return; } public double [][] sumar() { double [][] tem = null; if (matrizA == null || matrizB == null) return tem; if (matrizA.length != matrizB.length || matrizA[0].length != matrizB[0].length) { return tem; } tem = new double [matrizA.length][matrizA[0].length]; for(int i = 0; i < matrizA.length; i++) for(int j = 0; j < matrizA[0].length; j++) tem[i][j] = matrizA[i][j] + matrizB[i][j]; return tem; } } // el siguiente programa se encarga de interactuar con la clase OperaMat import java.util.Scanner; public class Main { public static void main(String[] args) { OperaMat x = new OperaMat(); x.setMatrizA( OperaMat.capturar() ); OperaMat.mostrar( x.getMatrizA() ); x.setMatrizB( OperaMat.capturar() ); OperaMat.mostrar( x.getMatrizB() ); OperaMat.mostrar( x.sumar() ); } }

20

UAA Sistemas Electrnicos

Programacin en Java

Eduardo Serna-Prez

3.11 Clases anidadas


En la estructura de la clase los miembros de una clases pueden ser otras clases, clases anidadas u objetos. La utilizacin de clase anidadas se justifica cuando: Deben utilizarse varias instancias a1, a2, ... etc. de la misma clase. Los objetos de la clase A no pueden tener existencia independiente ms que como miembros de la clase contenedora B.

La situacin puede esquematizarse como sigue: class B { class A // clase anidada (clase miembro) { ... }; A a1, a2, a3; // Ok. B contiene objetos tipo A ... }; El identificador de una clase anidada est sujeto a las mismas reglas de acceso que los restantes miembros. Si una clase anidada se declara en la seccin private de la clase circundante, la clase anidada ser utilizable slo por los miembros datos de la clase que la circunde. A continuacin se muestra un ejemplo del empleo de clases anidadas, en esencia se vera que es un efecto muy similar a emplear el esquema de estructuras. De hecho es recomendable que el programador comience a utilizar este tipo de esquemas anidados ya que es la forma correcta de emplear el esquema de clases. Una clase que emplea clases anidadas y a su vez declararemos un vector de tipo Datos que manipulara los datos estadsticos de una ciudad y el numero de robos en esa ciudad. Los objetos Histogram podrn capturar datos relativos al nombre de una ciudad y el numero de robos en ella, posteriormente mostrara los datos en forma de tabular y el numero de robos para cada ciudad ser expresado adicionalmente con un histograma. Desarrollaremos los siguientes mtodos: Histogram( int ): mtodo constructor que recibe como parmetro el numero de casillas que se habilitaran para los datos del vector dinmico. El constructor se encargara de realizar el ciclo para definir el tamao del vector y asignar valores iniciales a cada componente del vector. captura( ): mtodo encargado de capturar los datos entidad y frecuencia de robos. mostrar( ): mtodo encargado de mostrar los datos del vector y el histograma relativo a la frecuencia de robos en cada entidad.

import java.lang.*; import java.util.Scanner; public class TestHistogram { public static void main(String [] args){ int n; System.out.print("cuantos son? "); Scanner s = new Scanner(System.in);

21

UAA Sistemas Electrnicos

Programacin en Java

Eduardo Serna-Prez

n = s.nextInt(); Histograma obj = new Histograma(n); obj.capturar(); obj.mostrar(); s.close(); } } class Histograma { public class Datos // clase interna a Histograma { public String ciudad; public int frecuencia; public Datos() {} } private int n; private Datos []vector; // vector de clases Histograma( int x ) { this.n = x; this.vector = new Datos[n]; for (int i = 0; i<n; i++) this.vector[i] = new Datos(); } public void capturar() { Scanner s = new Scanner(System.in); for (int i = 0; i<this.n; i++) { System.out.print("ciudad "); this.vector[i].ciudad = s.next(); System.out.print("frecuencia "); this.vector[i].frecuencia = s.nextInt(); } } public void mostrar() { for (int i = 0; i<n; i++) { System.out.print( vector[i].ciudad + " " ); for ( int j = 0; j< vector[i].frecuencia; j++ ) System.out.print("*"); System.out.println(); } } }

Las siguiente clase Romano emplea un mecanismo anidado para definir un arreglo de clases tipo Tupla, encargado de almacenar la informacin relativa a los valores que representan cada elemento involucrado en la generacin del numero romano.
public class TestRomano { public static void main(String[] args) { Romano x = new Romano(1001); System.out.println(x.getRomano()); System.out.println(new Romano("MMXI").getArabigo()); } }

22

UAA Sistemas Electrnicos

Programacin en Java

Eduardo Serna-Prez

class Romano { private String romano; private int arabigo; class Tupla { // clase interna que almacena el numero y su texto public String letra; public int numero; public Tupla(String letra, int numero) { this.letra = letra; this.numero = numero; } public Tupla() {} } // la tabla corresponde a los valores de cada numero romano private Tupla [] tabla = {new Tupla("M",1000),new Tupla("CM",900), new Tupla("D",500),new Tupla("CD",400),new Tupla("C",100), new Tupla("XC",90),new Tupla("L",50),new Tupla("XL",40), new Tupla("X",10),new Tupla("IX",9),new Tupla("V",5), new Tupla("IV",4),new Tupla("I",1)}; public Romano() {} /* el constructor se encarga de recorrer el vector buscando restar el valor correspondiente a cada numero e ir concatenando el valor en romano segn sea el caso */ public Romano(int numero) { StringBuffer cadena = new StringBuffer(); for(int i = 0; i < tabla.length; i++) while (tabla[i].numero <= numero){ cadena.append(tabla[i].letra); numero -= tabla[i].numero; } this.romano = cadena.toString(); } public Romano(String numero) { int i; for( i = 0; i < numero.length()-1; i++ ) { if(this.valor(numero.charAt(i))<this.valor(numero.charAt(i))) this.arabigo -= this.valor( numero.charAt(i) ); else this.arabigo += this.valor( numero.charAt(i) ); } this.arabigo += this.valor( numero.charAt(i) ); } private int valor(char c){ for (Tupla t: tabla) if ( t.letra.equals(String.valueOf(c)) ) return t.numero; return 0; } public String getRomano() { return romano; } public int getArabigo() {

23

UAA Sistemas Electrnicos

Programacin en Java

Eduardo Serna-Prez

return arabigo; } }

Bibliografa Nell Dale, Chip Weems, Mark Headington, Programming and Problem Solving whith Java, Jones & Bartlett, 2005, ISBN: 0-7637-3069-6. Luis Joyanes Aguilar y Matilde, Java 2 Manual de programacin, Osborne-Mc Graw Hill.

24