Está en la página 1de 41

1.

PROGRAMACIÓN ORIENTADA A OBJETOS

1.1 FUNDAMENTOS DE LA PROGRAMACIÓN ORIENTADA A OBJETOS


A lo largo de la evolución de la Informática como ciencia, surgieron diferentes paradigmas de
programación como la programación imperativa, estructurada, lógica, funcional y otras.
Un paradigma de programación es un conjunto de teorías, técnicas, métodos y procedimientos,
para el modelamiento (representación de la realidad) y el desarrollo de software.
Uno de los paradigmas que más éxito ha tenido y es ampliamente usado en la actualidad, es
la Programación Orientada a Objetos (POO), que surgió por los años 70 con el lanzamiento
del lenguaje de programación Smalltalk. Debido a sus características, la POO paulatinamente
fue adquiriendo importancia y durante las décadas de los 80 y 90 fue adoptada por diversos
lenguajes de programación.
La POO brinda numerosas ventajas para desarrollo de software, entre ellas:
 Legibilidad, por cuanto permite modelar la realidad de forma más natural y clara para el
desarrollador, en base a objetos independientes, que tienen propiedades y
comportamiento determinados posibilitando la interacción entre ellos, de forma similar
a como se presentan, comportan e interactúan los objetos en la vida real.
 Reusabilidad, los bloques de código, denominados clases, permiten ser empleados en
distintas aplicaciones donde son necesarios, luego, una aplicación nueva se construye
haciendo uso de las clases existentes y otras nuevas; de este modo, el número de
clases crece cada vez más, conformando enormes bibliotecas de software, probadas,
de libre de uso y disponibles para cualquier tipo de aplicación.
 Flexibilidad, porque permite una construcción modular del software, donde cada módulo
puede ser modificado o cambiado afectando mínimamente al resto de la aplicación.
 Mantenibilidad, debido a que el enfoque modular de la POO facilita el mantenimiento,
actualizaciones y/o escalamiento del software.

1.2 LA PROGRAMACIÓN ORIENTADA A OBJETOS


La POO se basa en elementos funcionales denominados: objetos; los objetos tienen
características (propiedades o atributos) y funciones (comportamiento), tal como los objetos
de la realidad. Por ejemplo, un televisor tiene como características: tamaño, color, marca,
modelo, etc., y cumple funciones como: encender, apagar, cambiar de canal, aumentar el
volumen, etc.
Un programa se desarrolla creando objetos de diferentes clases, los que interactúan entre sí
mediante el envío de mensajes entre ellos.
El POO se basa en los siguientes cuatro pilares fundamentales:
 Abstracción
 Encapsulamiento
1
 Herencia
 Polimorfismo

La abstracción es un proceso mental mediante el cual se aíslan conceptualmente los


elementos de mayor interés de la realidad, descartando los aspectos irrelevantes, para lograr
un modelo computacional más simple y manejable.
Por ejemplo, una computadora es vista de forma diferente por diferentes personas; por
ejemplo, un comerciante lo verá como una mercadería de cierto valor; un técnico en reparación
la verá como un equipo electrónico con sus diferentes componentes internos para
mantenimiento; para un estudiante la computadora será su principal herramienta de trabajo
para realizar sus tareas y proyectos; para un niño será una máquina de juegos, etc. Entonces
la abstracción consiste en que las diferentes personas consideran solo en los principales
aspectos de su interés, obviando los otros aspectos.

2
El encapsulamiento corresponde a la organización de los elementos internos que componen
una clase, con el propósito de lograr una unidad modular integral, que contenga todos los
elementos estructurales y funcionales necesarios para administrar y gestionar la misma.
El encapsulamiento proporciona también un mecanismo de ocultamiento de datos, que
consiste en encerrar los elementos internos de los objetos y solo publicar un conjunto limitado
de accesos simples (interface) para el manejo del objeto.

Por ejemplo, un automóvil es una entidad completamente independiente de su entorno y


dispone para los conductores un conjunto de controles sencillos (llave de encendido, volante,
pedales, caja de cambio, etc.) que son suficientes para conducir el mismo, ocultando la
complejidad inherente al mismo (operación del motor, sistema de cambio de velocidades,
sistema eléctrico, carburador o sistema de inyección, etc., etc.)
La herencia es la propiedad que permite que una o más clases pueda construirse a partir de
otra clase existente. Las clases derivadas o subclases (clases hijas) mantienen todas las
propiedades y operaciones de la superclase.
Esta característica evita la repetición de código, y establece una jerarquía de clases derivadas.

3
El polimorfismo literalmente es la "cualidad de tener más de una forma" y se refiere al hecho
de que una misma operación pueda tener un comportamiento diferente con distintos objetos.

1.3 CLASES
En general, una clase es un concepto abstracto que se usa para representar una familia de
objetos con características y funciones comunes, por ejemplo: la clase mamífero, la clase
persona, la clase automóvil, la clase mesa, etc.
En POO, una clase es una especificación genérica de la estructura y del comportamiento de
un conjunto de objetos con características y funciones similares, que se representan mediante
atributos y métodos respectivamente.
Las clases son los elementos primarios de la POO y son implementados en la etapa de
codificación de los programas y posibilitan la creación de objetos durante la ejecución de los
programas.
Una clase se identifica con un nombre único, usualmente con la inicial en mayúscula y contiene
atributos y métodos implementados.
En Java, la declaración de la clase se realiza con la palabra reservada class, seguida por el
nombre de la clase, de acuerdo a la siguiente estructura:
Definición de paquete
Importación de bibliotecas;
public class NombreClase{
declaración de atributos;
declaración de métodos;
}
La definición de un paquete es opcional, y determina la ruta relativa de la unidad de
almacenamiento donde se guardará el archivo que contiene la clase.

4
La importación de bibliotecas es opcional, pero facilita al momento de reusar clases existentes
predefinidas o definidas por el usuario.
La declaración de los atributos puede incluir definiciones de variables de cualquier tipo de dato
y referencias de cualquier clase.
La declaración de métodos debe incluir la implementación completa de las mismas (con
algunas excepciones que se estudiarán más adelante).
Gráficamente una clase se representa mediante un rectángulo con tres subdivisiones,
correspondiente al nombre de la clase, lista de atributos y lista de métodos

Java tiene una biblioteca (library) con aproximadamente 5000 clases implementadas y
disponibles para ser usada en diferentes tipos de aplicaciones, las cuales son descritas en la
documentación de Java (Javadoc).
Por ejemplo, dos de las clases más usadas son la clase Math y la clase String, cuya
representación gráfica es la siguiente:

5
Algunas clases representan conjuntos de objetos concretos, como la clase Automóvil o clase
Persona, y otros representan objetos abstractos como la clase Color, la clase Math,
CuentaBancaria, la clase Horarios, etc.

1.4 LA ABSTRACCIÓN
La abstracción aplicada a la POO, consiste en la definición de clases con las características
(atributos) y comportamiento (métodos) de los objetos, de mayor interés para una aplicación
concreta, omitiendo los demás aspectos; de esta manera, la clase tendrá solo los elementos
esenciales y útiles de los objetos.
Por ejemplo, si se desea crear una clase para realizar operaciones matemáticas en el plano
cartesiano, será necesario crear la clase Punto, cuyos atributos básicos serán las coordenadas
x e y; se excluyen otras características como ser: tamaño o grosor del punto, color del punto,
etc. Sin embargo, en una aplicación gráfica, donde los puntos serán visibles, el tamaño, forma
y color de los puntos serán atributos importantes.

1.5 ATRIBUTOS
Los atributos son las propiedades de una clase que representan a las características de los
objetos de esa clase.
Todos los objetos de una misma clase presentan características comunes, por ejemplo,
algunas características las personas reales son: nombre, edad, sexo, peso, estatura, etc.;
éstas características constituyen, entonces, los atributos de la clase Persona.
Los atributos pueden ser constantes y/o variables de cualquier tipo y/o referencias a objetos
de cualquier clase.
Una clase puede contener 0 o más atributos, sin restricciones de número.
El formato de definición de un atributo es el siguiente:
[visibilidad] [static] tipo/clase identificadorAtributo;
Los elementos entre corchetes son opcionales y pueden ser omitidos.
Ejemplo 1: Definir la clase denominada Punto, que represente un punto del plano cartesiano,
con dos atributos correspondientes a la abscisa y a la ordenada.

public class Punto{


public double x, y;
}

6
1.6 MÉTODOS
Los métodos son las operaciones o funciones que pueden realizar los objetos de cierta clase
y se definen e implementan cuando se crea la misma.
Los métodos constituyen el medio para solicitar a un objeto que realice alguna operación o
ejecute algún proceso, lo que se conoce como “enviar un mensaje”. Los diferentes objetos de
un programa interactúan entre sí mediante el envío de mensajes.
En Java, la estructura general de un método es la siguiente:
[visibilidad] [static] tipoRetorno nombreMetodo([lista parámetros]) [throws Excepciones] {
Instrucciones;
[return valor;]
}
El nombre del método debe ser único y su elección debe seguir las mismas reglas de la
nominación de elementos en Java.
La lista de parámetros describe el tipo o clase de cada dato que se pasa al método, seguido
por el nombre de variable o referencia de los argumentos.
El tipo de retorno del método es obligatorio y determina el tipo de dato del valor devuelto o
clase de la referencia a ser devuelto por el método. Cuando el método no devuelve ningún
valor el tipo de retorno debe ser void.
Cuando un método devuelve un valor o referencia, se emplea en el bloque de código la palabra
reservada: return, seguido por el elemento a ser devuelto.

1.7 CONSTRUCTORES
Un método muy importante de las clases se denomina: constructor, que es un método que
Java lo proporciona por defecto, el cual se crea implícitamente (no es visible), lleva el nombre
de la clase, es público, carece de argumentos y tiene un bloque de código vació.
El método constructor se usa toda vez que se crea un objeto.
Ejemplo 2: Crear la clase Punto con los atributos correspondientes a las coordenadas de un
punto en el plano cartesiano y el método constructor por defecto.

public class Punto{


public double x, y;
}

7
1.8 SOBRECARGA DE MÉTODOS
La sobrecarga de métodos permite definir dos o más métodos con el mismo nombre o
identificador, pero con diferentes tipos y/o número de parámetros; esto permite realizar
diferentes formas de usar el mismo método, otorgando mayor flexibilidad a la clase que los
contiene.
En el caso del método constructor, es usual sobrecargar este método para añadir código a ser
ejecutado durante la instanciación del objeto.
Ejemplo 3: Crear la clase Punto con un par de métodos constructores sobrecargados y los
métodos módulo y ángulo, que devuelva la distancia del origen al punto y el ángulo del módulo.

public class Punto {


public double x, y;

public Punto() {
x = 0;
y = 0;
}
public Punto(double x, double y) {
this.x = x;
this.y = y;
}
public double modulo() {
return Math.sqrt(x * x + y * y);
}
public double angulo() {
return Math.atan2(x, y);
}
}

1.9 LA PALABRA THIS


La palabra reservada: this, es una referencia que apunta al objeto actual, es decir, el objeto
que está haciendo uso del método en ejecución.
A través de this, se puede acceder a los atributos y a los métodos de una instancia.

8
Ejemplo 4: Escribir un programa que instancie un objeto y acceda a un atributo y un método
del mismo mediante la palabra: this.
public class Ejemplo {
int variable = 10;

public static void main(String[] args) {


Ejemplo ejem=new Ejemplo(); // crea un objeto
ejem.imprimir(20); // accede e imprime la variable de método
ejem.imprimir(); // accede e imprime la variable del objeto
}
public void imprimir() {
System.out.println(this.variable);
}
public void imprimir(int variable) {
System.out.println(variable);
}

1.10 PAQUETES

Cuando las aplicaciones contienen numerosas clases, es conveniente almacenarlas en


carpetas separadas, agrupadas por su funcionalidad, lo que da lugar a los paquetes.
Un paquete es un contenedor de clases, que agrupa a un conjunto de clases afines entre sí;
físicamente un paquete define una ruta relativa a una carpeta o subcarpeta en la unidad de
almacenamiento.
La definición de un paquete requiere especificar la ruta donde se almacenará la clase al
principio de la clase, de la forma siguiente:

package rutaRelativa;

La rutaRelativa es una secuencia de nombres separados por puntos, cada nombre representa
una carpeta y cada punto indica que dentro de la carpeta existe una subcarpeta con el nombre
que sigue. Por ejemplo, la especificación java.util.Scanner; indica que existe una carpeta
accesible denominada: java, dentro de la cual se encuentra otra carpeta de nombre: útil y
dentro de ella existe el archivo denominado: Scanner.

Ejemplo 5: Crear un proyecto Java y definir la clase Punto en los tres siguientes paquetes:
paquete por defecto, Paquete1, Paquete2, Paquete1.Subpaquete y usarlos desde el método
principal.

1.11 MODIFICADORES DE ACCESO (VISIBILIDAD)


Los modificadores de acceso determinan el alcance o visibilidad, de las clases, atributos y
métodos de un programa, es decir, el ámbito donde un elemento es visible; éstos son:
public o público (+)
9
protected o protegido (#)
default (por defecto)
private o privado (-)

El modificador público, define el mayor alcance o visibilidad de un elemento, siendo


completamente accesible, sin restricción alguna.
El modificador protegido, determina que el elemento sea accesible desde todas las clases de
mismo paquete y desde las subclases (herederas) de otros paquetes.
El modificador por defecto, define que el elemento solo sea accesible desde las clases del
mismo paquete.
El modificador privado, determina que un elemento sea accesible solo desde la clase que la
define.
La siguiente tabla resume los diferentes tipos de acceso.

MODIFICADOR / ACCESO Todos Sublcase Paquete Clase


public si si si si
protegido no si si si
por defecto no no si si
privado no no no si

Atendiendo el principio de ocultamiento de datos, y con algunas excepciones, es una práctica


común que los atributos de un objeto se declaran privados para evitar que sean accedidos
directamente desde otra clase; y en los casos que se requiera un acceso a los atributos
privados se agregan métodos conocidos como geter y seter que permiten leer y escribir los
valores de tales atributos.

10
Ejemplo 6: Definir la clase Punto, añadiendo constructores, modificadores de acceso y
métodos geter y seter.

public class Punto {


private double x, y;

public Punto() {
x = 0;
y = 0;
}
public Punto(double x, double y) {
this.x = x;
this.y = y;
}
public double modulo() {
return Math.sqrt(x * x + y * y);
}
public double angulo() {
return Math.atan2(x, y);
}
public double getX() {
return this.x;
}
public void setX(double x) {
this.x=x;
}
public double getY() {
return this.y;
}
public void setY(double y) {
this.y=y;
}
}

11
1.12 OBJETOS
Un objeto es una instancia o un ejemplar particular de una clase, que tiene sus propios datos
que lo distingue de otros objetos de la misma clase y responde al conjunto de operaciones o
métodos comunes definidos en la clase. Por ejemplo, al conjunto de los universitarios de la
UAJMS podría representarse con la clase Universitario, y cada estudiante en particular
correspondería a una instancia u objeto de esa clase.
Todo objeto debe necesariamente debe pertenecer a una clase, por lo tanto, primero se define
la clase y después se pueden crear los objetos como instancias de esa clase. En consecuencia,
no puede existir un objeto sin que exista la clase correspondiente.
A diferencia de las clases, los objetos ocupan un tamaño de memoria principal en función a la
cantidad y tipos de los atributos que contiene.
Todos los objetos de una misma clase tienen los mismos atributos de la clase (aunque
generalmente tienen valores diferentes); los valores de cada objeto determinan su estado, lo
que los distingue de los demás objetos de la misma clase.
El estado de un objeto puede cambiar según la ejecución de los programas, lo cual se logra
mediante el cambio de los valores de sus atributos.
Todos los objetos de una misma clase comparten el mismo conjunto de métodos definidos en
esa clase.
Los programas, aplicaciones y sistemas se construyen en base a objetos que interactúan o
colaboran entre sí; cada objeto cumple un rol o función específico en el contexto del programa
o de la aplicación.
Un objeto puede representar cualquier tipo de entidad física o abstracta, real o imaginario, de
forma que puede modelar infinidad de elementos de la realidad o concebidos por el hombre.
La creación o instanciación de un objeto generalmente se realiza con la palabra reservada new
y el uso de un método constructor, de la forma:
nombreClase nombreObjeto;
nombreObjeto = new metodoConstructor();
La primera instrucción crea una referencia a un objeto.
La segunda instrucción crea el objeto con la palabra reservada: new y el uso del método
constructor, y luego el objeto creado es apuntado por la referencia especificada.
Es muy usual que ambas instrucciones se fusionen en una sola línea, de la forma:
nombreClase nombreObjeto = new metodoConstructor();
Ejemplo 7: Escribir un programa que use la clase Punto, instancie dos objetos, les asigne
valores e imprima sus valores.
public class Principal {
public static void main(String[] args) {
12
Punto p1=new Punto();
p1.setX(2.35);
p1.setY(-5.35);
Punto p2=new Punto(-3.2, 7.35);
System.out.println("Punto 1: ("+p1.getX()+", "+p1.getY()+")");
System.out.println("Punto 2: ("+p2.getX()+", "+p2.getY()+")");
}
}

En el ejemplo anterior, tanto p1 como p2 son los identificadores de referencias que pueden
apuntar a los objetos instanciados; sin embargo, ambas referencias son completamente
independientes de los objetos y tienen la capacidad de apuntar a cualquier objeto de la clase
Punto o inclusive a ningún objeto, lo que se representa con la palabra reservada: null.
Ejemplo 8: Escribir un programa que instancie dos objetos de la clase Punto, les asigne
valores iniciales, los imprima, luego hacer que p1 apunte a p2, los imprima, y por último, asignar
a p2 el valor null y los imprima.
public class Principal {
public static void main(String[] args) {
Punto p1=new Punto();
p1.setX(2.35);
p1.setY(-5.35);
Punto p2=new Punto(-3.2, 7.35);
System.out.println("Punto 1: ("+p1.getX()+", "+p1.getY()+")");
System.out.println("Punto 2: ("+p2.getX()+", "+p2.getY()+")");
System.out.println();
p2=p1;
System.out.println("Punto 1: ("+p1.getX()+", "+p1.getY()+")");
System.out.println("Punto 2: ("+p2.getX()+", "+p2.getY()+")");
System.out.println();
p2=null;
System.out.println("Punto 1: ("+p1.getX()+", "+p1.getY()+")");
System.out.println("Punto 2: ("+p2.getX()+", "+p2.getY()+")");
}
}

Como se observa, al imprimir p2 después de la asignación p2=p1, ambas referencias imprimen


el valor de p1, porque p2 ahora apunta al mismo objeto apuntado por p1; y después de asignar
p2=null, se imprime un mensaje de excepción que es un error en el programa, debido a que
p2 deja de apuntar al objeto y no está asociado a ningún valor, por lo que no es posible imprimir
ningún valor, consecuentemente se genera una excepción.
Se debe observar también que el primer objeto, que inicialmente estaba siendo apuntado por
p2, queda sin acceso porque pierde su referencia, por lo que el recolector de basura lo elimina
automáticamente, liberando la región de memoria que ocupaba.

13
Ejemplo 9: Agregar a la clase Punto los métodos: reset(), imprimir(punto), imprimir(),
desplazar(dx, dy), distancia(punto1, punto2), distancia(punto), suma(punto1, punto2),
suma(punto) y escribir una clase principal que haga uso de los mismos
public class Punto {
private double x, y;

public Punto() {
x = 0;
y = 0;
}
public Punto(double x, double y) {
this.x = x;
this.y = y;
}
public double modulo() {
return Math.sqrt(x * x + y * y);
}
public double angulo() {
return Math.atan2(x, y);
}
public double getX() {
return this.x;
}
public void setX(double x) {
this.x=x;
}
public double getY() {
return this.y;
}
public void setY(double y) {
this.y=y;
}
public void reset() {
this.x=0;
this.y=0;
}
public void imprimir(Punto p) {
System.out.println("("+p.x+","+p. y+")");
}
public void imprimir() {
System.out.println("("+this.x+","+this.y+")");
}

public void desplazar(double dx, double dy) {


this.x=this.x+dx;
this.y=this.y+dy;
}
14
public double distancia(Punto p1, Punto p2) {
return Math.sqrt(Math.pow(p1.getX()-p2.getX(), 2)+Math.pow(p1.getY()-
p2.getY(), 2));
}
public double distancia(Punto p) {
return Math.sqrt(Math.pow(this.x-p.getX(), 2)+Math.pow(this.y-p.getY(), 2));
}
public Punto suma(Punto p1, Punto p2) {
Punto aux=new Punto();
aux.x=p1.getX()+p2.getX();
aux.y=p1.getY()+p2.getY();
return aux;
}
public Punto suma(Punto p) {
return new Punto(this.x+p.x, this.y+p.y);
}
}

public class Principal {


public static void main(String[] args) {
Punto p1=new Punto(2, 5);
Punto p2=new Punto(-3.2, 7.35);
p1.imprimir();
p2.imprimir();
p2.reset();
p2.imprimir();
p2.desplazar(-3, 8);
p2.imprimir();
p2.desplazar(2, -5);
p2.imprimir();
System.out.println(p1.distancia(p1, p2));
System.out.println(p2.distancia(p1, p2));
System.out.println(p1.distancia(p1));
System.out.println(p1.distancia(p2));
Punto p3=p1.suma(p1, p2);
p3.imprimir();
p3=p2.suma(p1, p2);
p3.imprimir();
p3=p1.suma(p1);
p3.imprimir();
p3.imprimir(p2);
p3.imprimir(p1.suma(new Punto(2,5)));
}
}

15
1.13 ATRIBUTOS DE CLASE Y DE INSTANCIA
En general, los atributos corresponden a las variables y/o referencias de los objetos, sin
embargo, ocasionalmente un atributo puede no pertenecer a ningún objeto en particular, sino
a la clase; por ello, en Java, se pueden distinguir dos tipos de atributos:
 Atributos de clase
 Atributos de instancia.
Un atributo de clase es aquel que pertenece a la clase, la cual se define con la palabra
reservada static; puede ser gestionado directamente desde algún método de la clase, por lo
que no se requiere ningún objeto para usarlo, sin embargo, si existen objetos declarados de
esa clase, éstos pueden acceder y gestionar al atributo de clase, siendo su valor común para
todos los objetos.
Ejemplo 10: Agregar a la clase Punto el atributo de clase denominado: contadorDePuntos,
que contenga el número de puntos que se han instanciado, modificar los métodos
constructores incrementando dicho atributo cada vez que se instancie un objeto y escribir un
programa principal para imprimir este valor cada vez que se crea un objeto.
public class Punto {
private double x, y;
public static int contadorDePuntos=0;

}

public Punto() {
x = 0;
y = 0;
contadorDePuntos++;
}

public Punto(double x, double y) {


this.x = x;
this.y = y;
contadorDePuntos++;
}

public class Principal {


public static void main(String[] args) throws Throwable {
System.out.println(Punto.contadorDePuntos);
Punto p1=new Punto(2, 5);
System.out.println(Punto.contadorDePuntos);
Punto p2=new Punto(-3.2, 7.35);
System.out.println(Punto.contadorDePuntos);
Punto p3=new Punto(8, 4);
System.out.println(Punto.contadorDePuntos);
Punto p4=new Punto(4.5, 2.3);
System.out.println(Punto.contadorDePuntos);

16
}
}
Un atributo de instancia es aquel que pertenece a cada objeto en particular y tiene un valor
específico para cada instancia de la clase que determina el estado del mismo. En el ejemplo
anterior, los valores de las coordenadas X y Y son exclusivos de cada objeto; es decir cada
objeto o instancia tiene sus propias coordenadas.

1.14 MÉTODOS DE CLASE Y DE INSTANCIA


En general, los métodos corresponden a las operaciones que pueden realizar los objetos, sin
embargo, ocasionalmente un método puede no pertenecer a un método, sino a una clase; por
ello, en Java, se pueden distinguir dos tipos de métodos:
 Métodos de clase
 Métodos de instancia
Un método de clase se define con la palabra static, lo que se significa que puede invocarse
desde la clase, sin necesidad de una instancia u objeto.
Ejemplo 11: Escribir un programa con el método estático saludo(), que imprima “Hola Mundo!”
en la pantalla.
public class principal {
public static void main(String[] args) {
saludo();
}
public static void saludo(){
System.out.println("Hola Mundo!");
}
}
Puede observarse que para al ejecutar el anterior programa no hubo necesidad de instanciar
ningún objeto puesto que los métodos main() y saludo() son métodos estáticos y se invocan
directamente desde la clase.
Para invocar un método estático desde otra clase, debe anteponerse al método el nombre de
la clase a la que pertenece. Un buen ejemplo de clase con métodos estáticos es la clase Math,
los cuales conforman operaciones matemáticas generales y pueden ser invocados sin
instanciar objetos de esa clase.
Escribir un programa modular, con métodos estáticos, que lea dos números enteros A y B
(A<B) y genere e imprima un número aleatorio entre A y B inclusive.
Un método de instancia es aquel que se invoca siempre sobre una instancia u objeto,
anteponiendo el nombre del objeto al nombre del método. Los métodos de instancia nunca
llevan la palabra static en su definición.
Ejemplo 12: Reescribir el programa con el método saludo() como un método de instancia.
public class principal {
17
public static void main(String[] args) {
principal objeto = new principal();
objeto.saludo();
}
public void saludo(){
System.out.println("Hola Mundo!");
}
}
Al igual que los atributos de instancia, los métodos de instancia no pueden ser gestionados
directamente por un método de clase, a no ser a través de la instancia correspondiente.
Cabe destacar que el método principal main() cumple la función de iniciador de un programa,
por lo tanto siempre será público y estático.
Una aplicación puede estar formada por varias clases, pero solo una debe contener al método
principal main(), específicamente la clase denominada: Principal, la cual únicamente debería
iniciar el programa y no constituirse en el programa central de una aplicación.

Una mala práctica de programación es centralizar gran parte de la aplicación en el método


principal.

18
1.15 HERENCIA
La herencia es un mecanismo de la POO que permite que una o más clases hereden la
estructura y funcionalidad de otra clase. La clase de la que se hereda se denomina superclase
clase antecesora o padre, mientras que cada clase heredera se denomina subclase, clase
extendida, derivada o hija.
La subclase extiende la estructura y funcionalidad de la superclase, heredando todos los
atributos y métodos de la misma; además la subclase puede redefinir los elementos heredados
y también puede agregar nuevos atributos y/o métodos.
La herencia está fuertemente influenciada por el principio de reutilización, lo que permite que
la subclase reutilice los atributos y métodos de la superclase.
En la programación en general, se presentan dos tipos de herencia:
 Herencia simple
 Herencia múltiple
La herencia simple consiste en que una clase solo puede heredar de una sola superclase.
La herencia múltiple consiste en que una clase puede heredar de una o más superclases.
Java solo permite la herencia simple, que consiste en la herencia de una sola superclase,
aunque puede lograrse un equivalente a la herencia múltiple mediante las interfaces.
Java está formado por miles de clases, organizadas en una estructura de tipo árbol; todas
ellas, incluso las implementadas por los usuarios, heredan directa o indirectamente de una
sola clase, denominada Object, que se constituye en la clase raíz de la estructura jerárquica.

19
La herencia, en Java, se implementa agregando a la definición de una clase la palabra extends
seguido por el nombre de la superclase.
Ejemplo 13: Escribir la clase Persona con los atributos nombre y ci con los métodos
apropiados, y luego la clase Estudiante con el atributo RU, que herede de Persona.

public class Persona{


String nombre;
String ci;
public void setNombre(String nombre){
this.nombre=nombre;
}
public String getNombre(){
return this.nombre;
}
public void setCi(String ci){
this.ci=ci;
}
20
public String getCi(){
return this.ci;
}
public String toString(){
String datos="NOMBRE: "+this.nombre+"; CI: "+this.ci;
return datos;
}
}
public class Estudiante extends Persona{
int RU;
public Estudiante(String nombre, String ci, int RU){
this.nombre=nombre;
this.ci=ci;
this.RU=RU;
}
public int getRU(){
return RU;
}
public void setRU(int ru){
RU=ru;
}
public String toString(){
String datos="NOMBRE: "+this.nombre+"; CI: "+this.ci+"; RU: "+this.RU;
return datos;
}
}
La herencia se extiende desde la clase raíz a todas las clases derivadas en la jerarquía de
herencia de Java, en consecuencia todas las clases heredan los métodos de la clase Object,
tales como toString(), equals(), getClass() y otros, a no ser que se redefinan, por ejemplo:
Ejemplo 14:
public class Ejemplo {
int i=12345;
public static void main(String[] args) {
Ejemplo eje = new Ejemplo();
System.out.println(eje.toString());
}
}
Ejemplo 15: Para obtener un resultado más particular, es conveniente redefinir el método
toString() en la clase Ejemplo; de la siguiente forma:
public class Ejemplo {
static int i=12345;
public static void main(String[] args) {
Ejemplo eje = new Ejemplo();
System.out.println(eje.toString());
}
21
public String toString(){
return String.valueOf(i);
}
}
Muchas clases redefinen varios de los métodos heredados de forma que son más útiles para
los propósitos de las mismas.
Ejemplo 16:
import java.util.ArrayList;
public class Ejemplo {
public static void main(String[] args) {
Object a = 5;
System.out.println(a.toString());
Integer b = 23;
System.out.println(b.toString());
ArrayList c=new ArrayList();
c.add(10);
c.add("hola");
c.add(32.32);
System.out.println(c.toString());
}
}
Uno de los métodos heredados de la clase Object que tiene mucha utilidad es el método
equals() que permite comparar si dos objetos son exactamente iguales y con los mismos datos,
para ello, cada clase deberá redefinir el método equals() en función de los atributos que posea,
por ejemplo:
Ejemplo 17: Redefinir el método equals() en la clase Persona y en la clase Estudiante y
comparar dos objetos.
public class Persona{
String nombre;
String ci;
public void setNombre(String nombre){
this.nombre=nombre;
}
public String getNombre(){
return this.nombre;
}
public void setCi(String ci){
this.ci=ci;
}
public String getCi(){
return this.ci;
}
public String toString(){
String datos="NOMBRE: "+this.nombre+"; CI: "+this.ci;
22
return datos;
}
private void imprimirNombre(){
System.out.println(nombre);
}
public void secreto(){
imprimirNombre();
}
public boolean equals(Object objeto){
if(objeto==null)return false;
else if(objeto.getClass() != this.getClass()) return false;
Persona aux=(Persona) objeto;
return this.nombre.equals(aux.getNombre())
&& this.ci==aux.getCi();
}
}

public class Estudiante extends Persona{


int RU;
public Estudiante(String nombre, String ci, int RU){
this.nombre=nombre;
this.ci=ci;
this.RU=RU;
}
public int getRU(){
return RU;
}
public void setRU(int ru){
RU=ru;
}
public String toString(){
String datos=super.toString()+"; RU: "+this.RU;
return datos;
}
public boolean equals(Object objeto){
if(objeto==null)return false;
else if(objeto.getClass() != this.getClass()) return false;
Estudiante aux=(Estudiante) objeto;
return this.nombre.equals(aux.getNombre())
&& this.ci==aux.getCi() && this.RU==aux.getRU();
}
}

public class principal {

public static void main(String[] args) {


Persona p=new Persona();
Persona q=new Persona();

23
p.setNombre("Juan");
q.setNombre("Juan");
Estudiante e=new Estudiante("Juan", "23", 234);
if(p.equals(q)) System.out.println("si");
else System.out.println("no");
if(e.equals(p)) System.out.println("si");
else System.out.println("no");
}
}
Para evitar que un método sea redefinido en la subclase, se debe anteponer la palabra final a
la cabecera de su definición.
Para evitar que una clase pueda ser heredada, se antepone la palabra final a la cabecera de
su definición. Por ejemplo, las clases Math y String son clases no heredables.

1.16 LA PALABRA SUPER


La palabra reservada super, permite a una subclase acceder directamente a los métodos de
la superclase; es muy usada para invocar a los constructores.
Ejemplo 18: Escribir un programa con una subclase cuyo constructor use el constructor de la
superclase.
public class Persona{
String nombre;
String ci;
public Persona(String nombre, String ci) {
this.nombre=nombre;
this.ci=ci;
}
}

public class Estudiante extends Persona{


int RU;
public Estudiante(String nombre, String ci, int RU){
super(nombre, ci);
this.RU=RU;
}
public String toString(){
String datos="NOMBRE: "+this.nombre+"; CI: "+this.ci+"; RU: "+this.RU;
return datos;
}
}

public class Ejemplo {


public static void main(String[] args) {
Estudiante est=new Estudiante("Juan", "12345", 88888);
System.out.println(est.toString());
}
}

24
1.17 POLIMORFISMO
El polimorfismo es una característica de la POO que consiste en la definición de clases distintas
(semejantes) que tienen métodos idénticos, pero con comportamientos distintos.
El principio del polimorfismo radica en que una superclase puede referenciar (apunta) a objetos
o instancias de sus subclases, por ejemplo:
Ejemplo 19:
public class principal {

public static void main(String[] args) {


Persona p=new Persona();
Persona q=new Estudiante("Pedro", "2222222", 22222);
Estudiante e=new Estudiante("María", "3333333", 33333);
p.setNombre("Juan");
Object o=new Estudiante("Clara", "444444", 44444);
o=p;
o=e;
}
}
En este ejemplo, las referencias de la clase Persona (o superclase de ésta) pueden ser usada
para apuntar a objetos de la clase Persona y Estudiante, porque al tratarse de una superclase,
engloba a todas las clases descendientes; en consecuencia, cualquier objeto de la clase
Estudiante, que haya redefinido sus métodos, tendrá un comportamiento distinto, aunque el
método sea el mismo que de la superclase. En consecuencia, una referencia a la clase Object,
puede apuntar a cualquier instancia de cualquier clase, por ser Object la clase más jerárquica.
Ejemplo 20: El siguiente ejemplo muestra como el método mostrarPersona(), que recibe un
objeto de la clase Persona como argumento, despliega correctamente los datos del objeto
correspondiente, mediante el método toString(), el cual tiene un comportamiento distinto en
cada una de las clases derivadas:
import java.util.*;
public class Ejemplo{
public static void main (String[] args) {
Persona emp1= new Estudiante("Pedro", "3333", 1234);
Persona emp2=new Administrativo("Juan", "1234", 10);
Persona emp3=new Docente("María", "2222", 15);
mostrarPersona(emp1);
mostrarPersona(emp2);
mostrarPersona(emp3);
}
public static void mostrarPersona(Persona emp){
System.out.println(emp.toString()+", Soy un "+emp.getClass().getName());
}
}

25
Ejemplo 21:
import java.util.LinkedList;
public class pruebita2 {
public static void main(String[] args) {
LinkedList<Persona> listita=new LinkedList<Persona>();
Persona emp1= new Estudiante("Pedro", "3333", 1234);
Persona emp2=new Administrativo("Juan", "1234", 10);
Persona emp3=new Docente("María", "2222", 15);
listita.add(emp1);
listita.add(emp2);
listita.add(emp3);
for(int i=0; i<listita.size(); i++)
System.out.println(listita.get(i).toString());
}
}

1.18 CLASES ABSTRACTAS


Una clase abstracta es una clase especial que modela un concepto abstracto general de un
conjunto de objetos.
Una clase abstracta se caracteriza porque:
 Tiene, al menos, un método abstracto, el cual se caracteriza por tener la definición o
encabezado del método abstracto sin ningún código asociado.
 No permite instanciar objetos de dicha clase.
 Puede contener métodos que no son abstractos.
 Permite la herencia, luego, la subclase debe implementar todos los métodos abstractos
de la superclase, caso contrario ésta es también abstracta.
El propósito de las clases abstractas es otorgar a las clases descendientes la posibilidad de
especificar comportamientos diferentes o particulares para uno de los métodos abstractos, los
cuales deben ser implementados en clases descendientes.
La declaración de una clase abstracta, así como cada uno de sus métodos abstractos, deben
llevar la palabra reservada: abstract en su cabecera.
En la representación gráfica, tanto el nombre de la clase abstracta como cada uno de los
métodos abstractos se escriben en itálica o cursiva.
Ejemplo 22: Escribir la clase abstracta Persona y el método abstracto toString(), las cuales se
representan en cursiva o itálica en el lenguaje de modelado UML:

26
public abstract class Persona{
String nombre;
String ci;
public void setNombre(String nombre){
this.nombre=nombre;
}
public String getNombre(){
return this.nombre;
}
public void setCi(String ci){
this.ci=ci;
}
public String getCi(){
return this.ci;
}
abstract public String toString();
}
Ejemplo 23: Implementar la siguiente estructura de clases

public abstract class Empleado extends Persona{


int antiguedad;
27
public Empleado(String nombre, String ci, int antiguedad){
this.nombre=nombre;
this.ci=ci;
this.antiguedad=antiguedad;
}
public void setAntiguedad(int antiguedad){
this.antiguedad=antiguedad;
}
public int getAntiguedad(){
return this.antiguedad;
}
public String toString(){
String datos="NOMBRE: "+this.nombre+"; CI: "+this.ci+"; Antiguedad:
"+this.antiguedad;
return datos;
}
abstract int calcularSalario();
}
public class Administrativo extends Empleado{
public String toString(){
return super.toString()+"; Salario: "+calcularSalario();
}
public int calcularSalario(){
int salario=2000;
return salario;
}
}
import java.util.Vector;
public class Docente extends Empleado{
Vector materias=new Vector();
public Vector getMaterias(){
return materias;
}
public void setMaterias(Vector materias){
this.materias=materias;
}
public Docente(String nombre, String ci, int antiguedad){
super(nombre, ci, antiguedad);
}
public String toString(){
String datos=super.toString()+"; Salario: "+calcularSalario();
if(materias!=null && materias.size()!=0){
for(int i=0; i<materias.size(); i++) datos=datos+"; Mat("+i+1+"):
"+materias.get(i);
}
return datos;
}
public int calcularSalario(){

28
int salario=5000;
return salario;
}
}

1.19 INTERFACES
Una interface es una clase especial que define únicamente las cabeceras de los métodos, por
tanto, al igual que los métodos abstractos, no contienen código. En consecuencia, una
interface puede considerarse una clase abstracta pura porque no implementa ninguno de sus
métodos.
A diferencia de las clases abstractas, las interfaces no permiten la herencia, en su lugar, las
clases pueden implementar una o varias interfaces, lo que puede verse como un mecanismo
similar a la herencia múltiple, lo que constituye una ventaja.
La clase que implementa una interface está obligada a implementar todos los métodos de la
interface.
Conceptualmente, una interface es similar a un contrato o convenio que las clases que la
implementan deben respetar.
La declaración de una interface se realiza con la palabra reservada interface, en lugar de class,
y las clases que la implementan agregan, a la declaración de la clase, la palabra reservada
implements seguido por el nombre/s de la/s interface/s.
Ejemplo 24: Escribir una interface de nombre Materia, que tenga los métodos:
asignarMateria(materia), eliminarMateria(i) y getMateria(i), y modificar la clase Docente para
que implemente la interface Materia, de forma que se le pueda asignar y eliminar materias.
public interface Materia{
public void asignarMateria(String materia);
public void eliminarMateria(int i);
public String getMateria(int i);
}
import java.util.Vector;
public class Docente extends Empleado implements Materia{
Vector materias=new Vector();
public Vector getMaterias(){
return materias;
}
public void setMaterias(Vector materias){
this.materias=materias;
}
public Docente(String nombre, String ci, int antiguedad){
super(nombre, ci, antiguedad);
}
public String toString(){
String datos=super.toString()+"; Salario: "+calcularSalario();
if(materias.size()!=0){
29
for(int i=0; i<materias.size(); i++) datos=datos+"\n Mat("+(i+1)+"):
"+materias.get(i);
}
return datos;
}
public int calcularSalario(){
int salario=5000;
return salario;
}
public void asignarMateria(String materia){
materias.add(materia);
}
public String getMateria(int i){
return (String) materias.get(i);
}
public void eliminarMateria(int i){
materias.remove(i);
}
}

1.20 RELACIONES ENTRE CLASES


Las aplicaciones de software que usan varias clases generalmente crean varias instancias que
interactúan entre sí, de forma similar a como distintos objetos de la vida real interactúan entre
ellos, lo que se logra estableciendo relaciones entre las clases.
Una relación entre clases es una conexión semántica, que permite la interacción y/o
colaboración entre ellas, se implementa mediante el establecimiento de una referencia de una
clase hacia otra, ya sea mediante atributos, parámetros de funciones y/o mediante la herencia.
Las clases pueden presentar diferentes relaciones entre ellas, las más comunes son:
 Dependencia (relación de uso)
 Asociación (agregación, composición) (relación todo/parte)
 Generalización / especialización (relaciones de herencia)

1.21 DEPENDENCIA
La dependencia es la relación más básica, débil y transitoria entre dos clases y se presenta
cuando una clase eventualmente usa algún servicio de otra clase; el servicio puede ser algún
atributo o método.
En UML (Unified Modeling Language) o lenguaje de modelado para la representación gráfica
de sistemas de software, la dependencia se representa mediante una línea discontinua con
una flecha hacia la clase que se usa, como se muestra en la siguiente figura:

30
En esta representación, la ClaseA usa a la ClaseB, por lo cual la ClaseA depende de la ClaseB,
esto significa que algún cambio en la ClaseB, podría afectar a la ClaseA. Por otra parte, la
ClaseB no tiene dependencia de la ClaseA.
Dado que la relación es débil, la implementación en Java se realiza pasando a la ClaseB por
argumentos a algún método de la ClaseA o bien que la ClaseA instancie a la ClaseB dentro de
alguno de sus métodos para que tenga una existencia temporal.
Ejemplo 25: Escribir un programa que conste de las clases Principal, Ecuacion y las clases
complementarias, que permita resolver la ecuación cuadrática con coeficientes enteros.

public class Ecuacion {


private int A, B, C;
private double x, y;

public Ecuacion(int A, int B, int C) {


this.A=A;
this.B=B;
this.C=C;
resolver();
}

private void resolver() {


x=(-B+Math.sqrt(Math.pow(B, 2.)-4*A*C))/(2*A);
y=(-B-Math.sqrt(Math.pow(B, 2.)-4*A*C))/(2*A);
}
31
public void imprimir() {
System.out.println("x = "+x);
System.out.println("y = "+y);
}
}

import java.util.Scanner;

public class Principal {


public static void main(String[] args) {
Scanner tec=new Scanner(System.in);
int A=tec.nextInt();
int B=tec.nextInt();
int C=tec.nextInt();
Ecuacion ec=new Ecuacion(A, B, C);
ec.imprimir();
}
}

En el futuro, las clases predefinidas no se representarán en el diagrama de clases, porque


generalmente existe una evidente relación de dependencia con ellas.

1.22 ASOCIACIÓN
La asociación establece una relación fuerte o estructural entre clases; se representa mediante
una línea continua que une las clases relacionadas y opcionalmente un nombre de la relación.
La asociación se identifica cuando al emplear el término “usa”, la relación entre dos clases
tiene sentido, por ejemplo: “un chofer usa un vehículo”.
Es importante identificar la asociación con un nombre que describa la acción de una clase en
relación a la otra. Por ejemplo, la asociación entre las clases Chofer y Vehiculo se podría
representar como:

La relación se interpreta de la forma siguiente: un chofer conduce un vehículo, o bien: un


vehículo es conducido por un chofer.
Las asociaciones generalmente son bidireccionales, porque es factible transitar en ambos
sentidos, es decir, ambas clases conocen o “ven” a la otra clase; sin embargo, ocasionalmente
se establecen asociaciones unidireccionales, en tal caso se añade una flecha en el extremo
de la línea que une a la clase destino.

32
Las asociaciones tienen atributos de multiplicidad, que establece la cantidad de objetos destino
a los que el objeto de origen se puede relacionar, expresado mediante una notación numérica
en el extremo destino de la relación, de acuerdo a la siguiente tabla:
Multiplicidad Significado
1 uno y sólo uno
* muchos
0..1 cero o uno
0..* cero o muchos
1..* uno o muchos
N..M desde N hasta M

La implementación de una asociación se realiza creando un atributo que referencia a la clase


destino en la clase origen, si la asociación es unidireccional y además un atributo que
referencia a la clase origen en la clase destino, si la asociación es bidireccional.
Si la multiplicidad es 0, la referencia puede ser null; si la multiplicidad es 1, la referencia debe
estar vinculada a un objeto; si la multiplicidad es muchos, la referencia se vinculará a un arreglo
de objetos o una lista de objetos.
Ejemplo 26: Dibujar un diagrama de clases que ilustre el uso de la multiplicidad entre
diferentes clases.

Dos tipos de asociaciones especiales, que establecen una relación: Todo / Parte, que en
conjunto colaboran a un objetivo común, son:
 Agregación
 Composición

1.23 LA AGREGACIÓN
La agregación es un tipo de asociación en la que las partes tienen una existencia y ciclo de
vida independientes; esto significa que la eliminación de la clase que representa el todo no
destruye a la parte.
33
La agregación se representa con una línea continua y un rombo vacío en el extremo de la clase
que representa el todo. En la siguiente figura, la ClaseA constituye el todo, mientras que la
ClaseB constituye la parte.

Para fines de implementación, la instancia de las parte (instancias de la ClaseB) se pasa por
parámetros a uno o más métodos de la clase todo (ClaseA), de forma que, al eliminar la
instancia contenedora (instancia de ClaseA), no se elimina la instancia agregada (instancias
de ClaseB).
Ejemplo 27: Escribir un programa que defina las clases Materia, Docente, Universitario y
Curso, en un contexto similar al sistema Tariquia, considerando que Materia está conformado
por: Docente, Universitario, Curso, entre otros.

import java.util.LinkedList;
import java.util.List;

public class Materia {

private String nombre;


private String sigla;

private Docente docente;


private List universitario;
private Curso curso;

public Materia() {
nombre = null;
sigla = null;
docente = null;
34
universitario = new LinkedList();
curso = null;
}
public Materia(String nombre, String sigla) {
this.nombre = nombre;
this.sigla = sigla;
this.docente=null;
universitario = new LinkedList();
this.curso=null;
}
public void setNombre(String nombre) {
this.nombre = nombre;
}
public String getNombre() {
return nombre;
}
public void setSigla(String sigla) {
this.sigla = sigla;
}
public String getSigla() {
return sigla;
}
public void setDocente(Docente docente) {
this.docente=docente;
}
public Docente getDocente() {
return docente;
}
public void setUniversitario(List universitario) {
this.universitario = universitario;
}
public List getUniversitario() {
return universitario;
}
public void setCurso(Curso curso) {
this.curso = curso;
}
public Curso getCurso() {
return curso;
}
public boolean agregarUniversitario(Universitario univ) {
if(!universitario.contains(univ)) {
universitario.add(univ);
return true;
} else return false;
}
public boolean removerUniversitario(Universitario univ){
if(universitario.contains(univ)) {

35
universitario.remove(univ);
return true;
}else return false;
}
}

public class Curso {

public class Universitario {

public class Docente {

1.24 LA COMPOSICIÓN
La composición es un tipo de asociación fuerte entre un todo y la parte que lo compone; en
este caso la parte no tienen existencia independiente, sino ambas clases comparten el ciclo
de vida del todo, de forma que, si se elimina el todo, también se elimina la parte.
La composición se representa con una línea continua y un rombo relleno (negro) en el extremo
de la clase que representa el todo.

La implementación de la composición se realiza especificando la creación de atributos que


referencian a las instancias de las partes dentro de la clase contenedora o todo.
De forma más estricta, las clases parte podrían ser clases internas de la clase contenedora, lo
cual garantiza que una instancia de una parte solo podría existir dependiente de una instancia
del todo.
Ejemplo 28: Escribir un programa que defina las clases: Materia, ProgramaAnalitico y Horario,
en el contexto del sistema Tariquia.

import java.util.Date;
36
import java.util.LinkedList;
import java.util.List;

public class Materia {

private String nombre = null;


private String sigla = null;

private ProgramaAnalitico programa;


private List horario;

public Materia(String nombre, String sigla) {


this.nombre = nombre;
this.sigla = sigla;
programa = null;
horario = new LinkedList();
}

public void setNombre(String nombre) {


this.nombre = nombre;
}
public String getNombre() {
return nombre;
}
public void setSigla(String sigla) {
this.sigla = sigla;
}
public String getSigla() {
return sigla;
}
public void setProgramaAnalitico(String nombrePrograma, String contenido) {
this.programa = new ProgramaAnalitico(nombrePrograma, contenido);
}
public boolean agregarHorario(String hora) {
Horario horaAux = new Horario(hora);
if(!horario.contains(hora)) {
horario.add(horaAux);
return true;
} return false;
}
public boolean borrarHorario(String hora){
Date horaAux = new Date(hora);
if(horario.contains(horaAux)) {
horario.remove(horaAux);
return true;
}else return false;
}
}

37
public class ProgramaAnalitico {
String nombrePrograma;
String contenido;

public ProgramaAnalitico(String nombrePrograma, String contenido) {


this.nombrePrograma = nombrePrograma;
this.contenido = contenido;
}
public String toString() {
return nombrePrograma+"\n"+contenido;
}
}

import java.util.Date;

public class Horario {


private Date hora;

public Horario(String hora) {


this.hora = new Date(hora);
}
public void setHora(Date hora) {
this.hora = hora;
}
public Date getHora() {
return hora;
}
}
De forma más rigurosa, las clases Horario y ProgramaAnalitico podrían ser clases internas,
como sigue:
import java.util.Date;
import java.util.LinkedList;
import java.util.List;

public class Materia {

public class ProgramaAnalitico {


String nombrePrograma;
String contenido;

public ProgramaAnalitico(String nombrePrograma, String contenido) {


this.nombrePrograma = nombrePrograma;
this.contenido = contenido;
}

public String toString() {


38
return nombrePrograma + "\n" + contenido;
}
}

public class Horario {


private Date hora;

public Horario(String hora) {


this.hora = new Date(hora);
}

public void setHora(Date hora) {


this.hora = hora;
}

public Date getHora() {


return hora;
}
}

private String nombre = null;


private String sigla = null;

private ProgramaAnalitico programa;


private List horario;

public Materia(String nombre, String sigla) {


this.nombre = nombre;
this.sigla = sigla;
programa = null;
horario = new LinkedList();
}

public void setNombre(String nombre) {


this.nombre = nombre;
}

public String getNombre() {


return nombre;
}

public void setSigla(String sigla) {


this.sigla = sigla;
}

public String getSigla() {


return sigla;
}

39
public void setProgramaAnalitico(String nombrePrograma, String contenido) {
this.programa = new ProgramaAnalitico(nombrePrograma, contenido);
}

public boolean agregarHorario(String hora) {


Horario horaAux = new Horario(hora);
if (!horario.contains(hora)) {
horario.add(horaAux);
return true;
}
return false;
}

public boolean borrarHorario(String hora) {


Date horaAux = new Date(hora);
if (horario.contains(horaAux)) {
horario.remove(horaAux);
return true;
} else
return false;
}
}

1.25 GENERALIZACIÓN/ESPECIALIZACIÓN
Esta relación de clases está basada en la característica de herencia de la POO; establece una
relación jerárquica entre una clase general, denominada superclase y una o más clases
específicas (subclases), que contienen las características y el comportamiento de la
superclase, además de propiedades y/o comportamiento específico de las subclases.
La generalización/especialización se representa con una línea que consta de un triángulo en
el extremo de la superclase, como muestra la siguiente figura:

40
El nombre de generalización o especialización se aplica de acuerdo orden del diseño realizado;
si primero se define la superclase y luego las subclases, se denomina: especialización; en
contraparte, si primero se definen las subclases para luego pasar a la superclase, este
procedimiento se denomina: generalización.

1.26 APLICACIONES
Actualmente, la POO es el principal paradigma de desarrollo de software y se aplica en la
mayoría de los proyectos de software en todos los ámbitos.
La POO es muy flexible al momento del diseño de las clases, sus propiedades y relaciones,
por ello un mismo proyecto puede tener diferentes diseños, tener diferentes implementaciones
y ser completamente funcionales, sin embargo, las diferencias pueden distinguir características
de software como mantenibilidad, escalamiento, portabilidad, etc. Un diseño de un proyecto de
software, además de satisfacer los requerimientos, debe ser cumplir con especificaciones de
calidad.
Las aplicaciones de la POO se realizarán directamente en el laboratorio.

41

También podría gustarte