▁ ▂ ▃ ▄ ▅ ▆ ▇ █▋ ▌Aprendiendo Java Fácil™ ▌▋█ ▇ ▅ ▄ ▃ ▂ ▁

  • CALENDARIO

    abril 2024
    L M X J V S D
    1234567
    891011121314
    15161718192021
    22232425262728
    2930  

Programacion Orientada a Objetos

Programación Orientada a Objetos

 

La orientación a objetos es un paradigma de programación que facilita la creación de software de calidad por sus factores que potencian el mantenimiento, la extensión y la reutilización del software generado bajo este paradigma.

La programación orientada a objetos trata de amoldarse al modo de pensar del hombre y no al de la máquina. Esto es posible gracias a la forma racional con la que se manejan las abstracciones que representan las entidades del dominio del problema, y a propiedades como la jerarquía o el encapsulamiento.

El elemento básico de este paradigma no es la función (elemento básico de la programación estructurada), sino un ente denominado objeto. Un objeto es la representación de un concepto para un programa, y contiene toda la información necesaria para abstraer dicho concepto: los datos que describen su estado y las operaciones que pueden modificar dicho estado, y determinan las capacidades del objeto.

Java incorpora el uso de la orientación a objetos como uno de los pilares básicos de su lenguaje.

Las clases

Las clases son abstracciones que representan a un conjunto de objetos con un comportamiento e interfaz común.

Podemos definir una clase como «un conjunto de cosas (físicas o abstractas) que tienen el mismo comportamiento y características… Es la implementación de un tipo de objeto (considerando los objetos como instancias de las clases)».

Una clase no es más que una plantilla para la creación de objetos. Cuando se crea un objeto (instanciación) se ha de especificar de qué clase es el objeto instanciado, para que el compilador comprenda las características del objeto.

Las clases presentan el estado de los objetos a los que representan mediante variables denominadas atributos. Cuando se instancia un objeto el compilador crea en la memoria dinámica un espacio para tantas variables como atributos tenga la clase a la que pertenece el objeto.

Los métodos son las funciones mediante las que las clases representan el comportamiento de los objetos. En dichos métodos se modifican los valores de los atributos del objeto, y representan las capacidades del objeto (en muchos textos se les denomina servicios).

Desde el punto de vista de la programación estructurada, una clase se asemejaría a un módulo, los atributos a las variables globales de dicho módulo, y los métodos a las funciones del módulo.

Los objetos

Podemos definir objeto como el «encapsulamiento de un conjunto de operaciones (métodos) que pueden ser invocados externamente, y de un estado que recuerda el efecto de los servicios«.

Un objeto además de un estado interno, presenta una interfaz para poder interactuar con el exterior. Es por esto por lo que se dice que en la programación orientada a objetos «se unen datos y procesos«, y no como en su predecesora, la programación estructurada, en la que estaban separados en forma de variables y funciones.

Un objeto consta de:

  • Tiempo de vida: La duración de un objeto en un programa siempre está limitada en el tiempo. La mayoría de los objetos sólo existen durante una parte de la ejecución del programa. Los objetos son creados mediante un mecanismo denominado instanciación, y cuando dejan de existir se dice que son destruidos.
  • Estado: Todo objeto posee un estado, definido por sus atributos. Con él se definen las propiedades del objeto, y el estado en que se encuentra en un momento determinado de su existencia.
  • Comportamiento: Todo objeto ha de presentar una interfaz, definida por sus métodos, para que el resto de objetos que componen los programas puedan interactuar con él.

El equivalente de un objeto en el paradigma estructurado sería una variable. Así mismo la instanciación de objetos equivaldría a la declaración de variables, y el tiempo de vida de un objeto al ámbito de una variable.

Modelo de objetos

Existen una serie de principios fundamentales para comprender cómo se modeliza la realidad al crear un programa bajo el paradigma de la orientación a objetos. Estos principios son: la abstracción, el encapsulamiento, la modularidad, la jerarquía, el paso de mensajes y el polimorfismo.

a.) Principio de Abstracción

Mediante la abstracción la mente humana modeliza la realidad en forma de objetos. Para ello busca parecidos entre la realidad y la posible implementación de objetos del programa que simulen el funcionamiento de los objetos reales.

Los seres humanos no pensamos en las cosas como un conjunto de cosas menores; por ejemplo, no vemos un cuerpo humano como un conjunto de células. Los humanos entendemos la realidad como objetos con comportamientos bien definidos. No necesitamos conocer los detalles de porqué ni cómo funcionan las cosas; simplemente solicitamos determinadas acciones en espera de una respuesta.

Pero la abstracción humana se gestiona de una manera jerárquica, dividiendo sucesivamente sistemas complejos en conjuntos de subsistemas, para así entender más fácilmente la realidad. Esta es la forma de pensar que la orientación a objeto intenta cubrir.

b.) Principio de Encapsulamiento

El encapsulamiento permite a los objetos elegir qué información es publicada y qué información es ocultada al resto de los objetos. Para ello los objetos suelen presentar sus métodos como interfaces públicas y sus atributos como datos privados e inaccesibles desde otros objetos.

Para permitir que otros objetos consulten o modifiquen los atributos de los objetos, las clases suelen presentar métodos de acceso. De esta manera el acceso a los datos de los objetos es controlado por el programador, evitando efectos laterales no deseados.

Con el encapsulado de los datos se consigue que las personas que utilicen un objeto sólo tengan que comprender su interfaz, olvidándose de cómo está implementada, y en definitiva, reduciendo la complejidad de utilización.

c.) Principio de Modularidad

Mediante la modularidad, se propone al programador dividir su aplicación en varios módulos diferentes (ya sea en forma de clases, paquetes o bibliotecas), cada uno de ellos con un sentido propio.

Esta fragmentación disminuye el grado de dificultad del problema al que da respuesta el programa, pues se afronta el problema como un conjunto de problemas de menor dificultad, además de facilitar la comprensión del programa.

d.) Principio de Jerarquía

La mayoría de nosotros ve de manera natural nuestro mundo como objetos que se relacionan entre sí de una manera jerárquica. Por ejemplo, un perro es un mamífero, y los mamíferos son animales, y los animales seres vivos…

Del mismo modo, las distintas clases de un programa se organizan mediante la jerarquía. La representación de dicha organización da lugar a los denominados árboles de herencia:

Mediante la herencia una clase hija puede tomar determinadas propiedades de una clase padre. Así se simplifican los diseños y se evita la duplicación de código al no tener que volver a codificar métodos ya implementados.

Al acto de tomar propiedades de una clase padre se denomina heredar.

e.) Principio de Polimorfismo

Polimorfismo quiere decir «un objeto y muchas formas». Esta propiedad permite que un objeto presente diferentes comportamientos en función del contexto en que se encuentre. Por ejemplo un método puede presentar diferentes implementaciones en función de los argumentos que recibe, recibir diferentes números de parámetros para realizar una misma operación, y realizar diferentes acciones dependiendo del nivel de abstracción en que sea llamado.

===============================

Definición de una clase

Introducción

El elemento básico de la programación orientada a objetos en Java es la clase. Una clase define la forma y comportamiento de un objeto.

Para crear una clase sólo se necesita un archivo fuente que contenga la palabra clave reservada class seguida de un identificador legal y un bloque delimitado por dos llaves para el cuerpo de la clase.

class ClaseOperacion {

}

 

 

Un archivo de Java debe tener el mismo nombre que la clase que contiene, y se les suele asignar la extensión «.java».

Por ejemplo la clase ClaseOperacion se guardaría en un fichero que se llamase ClaseOperacion.java. Hay que tener presente que en Java se diferencia entre mayúsculas y minúsculas; el nombre de la clase y el de archivo fuente han de ser exactamente iguales.

 

Aunque la clase ClaseOperacion es sintácticamente correcta, es lo que se viene a llamar una clase vacía, es decir, una clase que no hace nada. Las clases típicas de Java incluirán variables y métodos de instancia. Los programas en Java completos constarán por lo general de varias clases de Java en distintos archivos fuente.

Una clase es una plantilla para un objeto. Por lo tanto define la estructura de un objeto y su interfaz funcional, en forma de métodos. Cuando se ejecuta un programa en Java, el sistema utiliza definiciones de clase para crear instancias de las clases, que son los objetos reales. Los términos instancia y objeto se utilizan de manera indistinta. La forma general de una definición de clase es:

class Nombre_De_Clase {

 

tipo_de_variable nombre_de_atributo1;

tipo_de_variable nombre_de_atributo2;

 

// . . .

 

tipo_dato  nombre_de_método1( lista_de_parámetros ) {

cuerpo_del_método1;

}

 

tipo_dato  nombre_de_método2( lista_de_parámetros ) {

cuerpo_del_método2;

}

 

// . . .

 

}

 

Los tipos tipo_de_variable y tipo_devuelto, han de ser tipos simples Java o nombres de otras clases ya definidas. Tanto Nombre_De_Clase, como los nombre_de_atributo y nombre_de_método, han de ser identificadores Java válidos.

 

Los atributos

Los datos se encapsulan dentro de una clase declarando variables dentro de las llaves de apertura y cierre de la declaración de la clase, variables que se conocen como atributos. Se declaran igual que las variables locales de un método en concreto.

Por ejemplo, este es un programa que declara una clase ClaseOperacion, con dos atributos enteros llamados x e y.

class ClaseOperacion {

int x, y;

}

 

Los atributos se pueden declarar con dos clases de tipos: un tipo simple Java (ya descritos), o el nombre de una clase (será una referencia a objeto).

Cuando se realiza una instancia de una clase (creación de un objeto) se reservará en la memoria un espacio para un conjunto de datos como el que definen los atributos de una clase. A este conjunto de variables se le denomina variables de instancia.

Ámbito de los Atributos

El ámbito de un atributo es el área del programa donde el atributo existe y puede ser utilizada. Fuera de ese ámbito el atributo, o bien no existe o no puede ser usada (que viene a ser lo mismo).

El ámbito de un atributo miembro (que pertenece a un objeto) es el de la usabilidad de un objeto. Un objeto es utilizable desde el momento en que se crea y mientras existe una referencia que apunte a él. Cuando la última referencia que lo apunta sale de su ámbito el objeto queda ‘perdido’ y el espacio de memoria ocupado por el objeto puede ser recuperado por la JVM cuando lo considere oportuno.

El ámbito de los atributos locales es el bloque de código donde se declaran. Fuera de ese bloque la variable es desconocida. Ejemplo:

{
int x;     // empieza el ámbito de x. (x es conocida y utilizable)

{
int q;    // empieza el ámbito de q. x sigue siendo conocida.      . . .

}              // finaliza el ámbito de q (termina el bloque de código)
. . .                          // q ya no es utilizable
}                // finaliza el ámbito de x

 

 

Los métodos

Los métodos son subrutinas que definen la interfaz de una clase, sus capacidades y comportamiento.

Un método ha de tener por nombre cualquier identificador legal distinto de los ya utilizados por los nombres de la clase en que está definido. Los métodos se declaran al mismo nivel que las variables de instancia dentro de una definición de clase.

 

La forma general de una declaración de método es:

 

tipo_dato  nombre_de_método( lista-formal-de-parámetros ) {

cuerpo_del_método;

}

 

 

Por ejemplo el siguiente método devuelve la suma de dos enteros:

 

int metodoSuma( int paramX, int paramY ) {

return ( paramX + paramY );

}

 

 

En el caso de que no se desee devolver ningún valor se deberá indicar como tipo la palabra reservada void. Así mismo, si no se desean parámetros, la declaración del método debería incluir un par de paréntesis vacíos (sin void):

void metodoVacio( ) { };

 

 

Los métodos son llamados indicando una instancia individual de la clase, que tendrá su propio conjunto único de variables de instancia, por lo que los métodos se pueden referir directamente a ellas.

 

El método inicia() para establecer valores a las dos variables de instancia sería el siguiente:

 

void inicia( int paramX, int paramY ) {

x = paramX;

y = paramY;

}

 

Métodos estáticos

Para los métodos, la idea es la misma que para los datos: los métodos estáticos se asocian a una clase, no a una instancia.

Por ejemplo:

 

class Punto {
int x , y ;
static int numPuntos = 0;

Punto ( int a , int b ) {
x = a ; y = b;
numPuntos ++ ;
}

static int cuantosPuntos() {
return numPuntos;
}
}

 

La sintaxis general para la definición de los métodos es, por tanto, la siguiente:

[modificadores ] Tipo_Valor_devuelto nombre_método ( lista_argumentos ) {
bloque_de_codigo;
}

 

El aceso a los métodos estáticos se hace igual que a los datos estáticos, es decir, usando el nombre de la clase, en lugar de usar una referencia:

int totalPuntos = Punto.cuantosPuntos();

Dado que los métodos estáticos tienen sentido a nivel de clase y no a nivel de objeto (instancia) los métodos estáticos no pueden acceder a datos miembros que no sean estáticos.

El método main

Un programa Java se inicia proporcionando al intérprete Java un nombre de clase. La JVM carga en memoria la clase indicada e inicia su ejecución por un método estático que debe estar codificado en esa clase.

El nombre de este método es main y debe declararse de la siguiente forma:

static void main ( String [] args)

  • Es un método estático. Se aplica por tanto a la clase y no a una instancia en particular, lo que es conveniente puesto que en el momento de iniciar la ejecución todavía no se ha creado ninguna instancia de ninguna clase.
  • Recibe un argumento de tipo String []. String es una clase que representa una cadena de caracteres ( se verá más adelante),
  • Los corchetes [] indican que se trata de un array que se verán en un capítulo posterior.

 

No es obligatorio que todas las clases declaren un método main . Sólo aquellos métodos que vayan a ser invocados directamente desde la línea de comandos de la JVM necesitan tenerlo. En la práctica la mayor parte de las clases no lo tienen.

La instanciación de las clases: Los objetos

Referencias a Objeto e Instancias

Los tipos simples de Java describían el tamaño y los valores de las variables. Cada vez que se crea una clase se añade otro tipo de dato que se puede utilizar igual que uno de los tipos simples. Por ello al declarar una nueva variable, se puede utilizar un nombre de clase como tipo. A estas variables se las conoce como referencias a objeto.

Todas las referencias a objeto son compatibles también con las instancias de subclases de su tipo. Del mismo modo que es correcto asignar un byte a una variable declarada como int, se puede declarar que una variable es del tipo MiClase y guardar una referencia a una instancia de este tipo de clase:

ClaseOperacion p;

Esta es una declaración de una variable p que es una referencia a un objeto de la clase ClaseOperacion, de momento con un valor por defecto de null.

El operador punto (.)

El operador punto (.) se utiliza para acceder a las variables de instancia y los métodos contenidos en un objeto, mediante su referencia a objeto:

referencia_a_objeto.nombre_de_variable_de_instancia

referencia_a_objeto.nombre_de_método( lista-de-parámetros );

La referencia this

Java incluye un valor de referencia especial llamado this, que se utiliza dentro de cualquier método para referirse al objeto actual. El valor this se refiere al objeto sobre el que ha sido llamado el método actual. Se puede utilizar this siempre que se requiera una referencia a un objeto del tipo de una clase actual. Si hay dos objetos que utilicen el mismo código, seleccionados a través de otras instancias, cada uno tiene su propio valor único de this.

Un refinamiento habitual es que un constructor llame a otro para construir la instancia correctamente. El siguiente constructor llama al constructor parametrizado ClaseOperacion(x,y) para terminar de iniciar la instancia:

 

ClaseOperacion() {

this( -1, -1 ); // Llama al constructor parametrizado

}

 

En Java se permite declarar variables locales, incluyendo parámetros formales de métodos, que se solapen con los nombres de las variables de instancia.

 

No se utilizan x e y como nombres de parámetro para el método inicia, porque ocultarían las variables de instancia x e y reales del ámbito del método. Si lo hubiésemos hecho, entonces x se hubiera referido al parámetro formal, ocultando la variable de instancia x:

 

void inicia2( int x, int y ) {

x = x;        // Ojo, no modificamos la variable de instancia!!!

this.y = y; // Modificamos la variable de instancia!!!

}