Descargar como pdf o txt
Descargar como pdf o txt
Está en la página 1de 15

INSTITUTO TECNOLÓGICO SUPERIOR DE TIERRA BLANCA

INGENIERÍA EN MECATRONICA

MATERÍA
PROGRAMACION AVANZADA
ALUMNO:
JOSE MUÑIZ BECERRA
NUMERO DE CONTROL:
188N0452
GRUPO:
608-D
FECHA DE ENTREGA:
8 DE MAYO DEL 2021

PRESENTA:
“INVESTIGACION 4”

DOCENTE:

ING. EVA MORA COLORADO

FEBRERO-JULIO 2021
TIERRA BLANCA, VER.
Índice
4.1 definición
poliformismo
4.2 Clases abstractas definición
 métodos abstractos
 implementación de clases abstractas
 modelado de clases abstractas
4.3 reutilización de código

Introducción
En esta investigación veremos cómo funcionan las clases abstractas en
programación es más utilizada en la orientación de objetos y los diferentes
lenguajes de la programación en los que se puede utilizar.

4.1 Definición
Polimorfismo

El polimorfismo es un concepto de la programación orientada a objetos


que nos permite programar en forma general, en lugar de hacerlo en forma
específica. En general nos sirve para programar objetos con
características comunes y que todos estos compartan la misma
superclase en una jerarquía de clases, como si todas fueran objetos de la
superclase. Esto nos simplifica la programación.

Para ponerlo en práctica se hará un ejemplo bastante sencillo. Se hará


una librería de clases que represente figuras tridimensionales y
bidimensionales, y su respectiva jerarquía de clases. Las clases deben
ser capaces de tener funcionamiento bastante básico, como obtener
áreas, volúmenes y perímetros de la figura correspondiente.

La representación de la jerarquía sería como ésta:

.
La superclase de dicha jerarquía podría ser muy parecida a ésta:
public abstract class figura {
protected String nombre;
protected int color;
protected int grosorBorde;

public String getNombre(){


return this.nombre;
}

public void setNombre(String n){


this.nombre=n;
}

public int getColor(){


return this.color;
}

public void setColor(int c){


this.color=c;
}

public int getGrosorBorde(){


return this.grosorBorde;
}

public void setGrosorBorde(int g){


this.grosorBorde=g;
}

public abstract void dibujar();


}

Las siguientes clases en el nivel de la jerarquía podrían quedar muy


parecidas a éstas:

public abstract class figura2D extends figura {


public abstract int calcularArea();
public abstract int calcularPerimetro();
}

public abstract class figura3D extends figura {

public abstract int calcularVolumen();


}

El polimorfismo en acción
Supongamos que deseamos saber la figura que tiene mayor área
independientemente de su forma. Primero, programamos una función que
halle el mayor de varios números reales positivos.
double valorMayor(double[] x){
double mayor=0.0;
for (int i=0; i<x.length; i++)
if(x[i]>mayor){
mayor=x[i];
}
return mayor;
}
Ahora, la llamada a la función valorMayor
double numeros[]={3.2, 3.0, 5.4, 1.2};
System.out.println("El valor mayor es "+valorMayor(numeros));
La función figuraMayor que compara el área de figuras planas es
semejante a la función valorMayor anteriormente definida, se le pasa el
array de objetos de la clase base Figura. La función devuelve una
referencia al objeto cuya área es la mayor.
static Figura figuraMayor(Figura[] figuras){
Figura mFigura=null;
double areaMayor=0.0;
for(int i=0; i<figuras.length; i++){
if(figuras[i].area()>areaMayor){
areaMayor=figuras[i].area();
mFigura=figuras[i];
}
}
return mFigura;
}
La clave de la definición de la función está en las líneas
if(figuras[i].area()>areaMayor){
areaMayor=figuras[i].area();
mFigura=figuras[i];
}

En la primera línea, se llama a la versión correcta de la


función areadependiendo de la referencia al tipo de objeto que guarda el
elemento figuras[i]del array. En areaMayor se guarda el valor mayor de
las áreas calculadas, y enmFigura, la figura cuya área es la mayor.
La principal ventaja de la definición de esta función estriba en que la
funciónfiguraMayor está definida en términos de variable figuras de la
clase baseFigura, por tanto, trabaja no solamente para una colección de
círculos y rectángulos, sino también para cualquier otra figura derivada de
la clase baseFigura. Así si se deriva Triangulo de Figura, y se añade a la
jerarquía de clases, la función figuraMayor podrá manejar objetos de
dicha clase, sin modificar para nada el código de la misma.
Veamos ahora la llamada a la función figuraMayor
Figura[] fig=new Figura[4];
fig[0]=new Rectangulo(0,0, 5.0, 7.0);
fig[1]=new Circulo(0,0, 5.0);
fig[2]=new Circulo(0, 0, 7.0);
fig[3]=new Rectangulo(0,0, 4.0, 6.0);
Figura fMayor=figuraMayor(fig);
System.out.println("El área mayor es "+fMayor.area());
Pasamos el array fig a la función figuraMayor, el valor que retorna lo
guardamos en fMayor. Para conocer el valor del área, desde fMayor se
llamará a la función miembro area. Se llamará a la versión correcta
dependiendo de la referencia al tipo de objeto que guarde por fMayor.
Si fMayor guarda una referencia a un objeto de la clase Circulo, llamará a
la función area definida en dicha clase. SifMayor guarda una referencia a
un objeto de la clase Rectangulo, llamará a la función area definida en
dicha clase, y así sucesivamente.
La combinación de herencia y enlace dinámico se denomina polimorfismo.
El polimorfismo es, por tanto, la técnica que permite pasar un objeto de
una clase derivada a funciones que conocen el objeto solamente por su
clase base.

El poder manipular un Objeto como si éste fuera de un tipo genérico


otorga mayor flexibilidad al momento de programar con Objetos, el
término Polimorfismo también es asociado con un concepto llamado Late-
Binding (Ligamiento Tardío), observe el siguiente fragmento de código:
Figura a = new Circulo();
Figura b = new Triangulo();
Inicialmente se puede pensar que este código generaría un error debido
a que el tipo de referencia es distinta a la instancia del objeto, sin embargo,
el fragmento anterior es correcto y demuestra el concepto de
Polimorfismo; para asentar este tema se describe un ejemplo más
completo:
Uso de Polimorfismo.
El uso de Polimorfismo posee ciertos detalles que no fueron descritos en
el ejemplo anterior, uno de estos, que también tiene implicaciones en otros
componentes es: Casting.
Uso de "Casting"
El termino "Casting" viene de la palabra "Cast" que significa Molde, por lo
que el termino literal es Hacer un Molde, en Polimorfismo se lleva acabo
este proceso de "Casting" implícitamente, una Guitarra se coloca en
el molde de unInstrumento, un Triangulo en el molde de una Figura, sin
embargo, en ciertas ocasiones se requiere realizar un tipo de "Casting"
que no es considerado seguro en términos computacionales.
Anteriormente se mencionó que el "Casting" llevado acabo con
Polimorfismo es implícito, esto se debe a que no se requiere de sintaxis
especial, simplemente se convierte una Guitarra a un Instrumento, sin
embargo, para llevar una transformación en sentido opuesto se requiere
de sintaxis adicional para mantener la seguridad de transformación;
analicemos: mientras se puede asegurar que un Triangulo es
una Figura ("Up-Casting"), una Figura no necesariamente es
un Triangulo, claro esta que lo puede ser, pero en Java se requiere definir
explícitamente esta operación ("Down-Casting").

El polimorfismo es una de las cualidades de más dificil comprensión de la


POO. Una de las ventajas de estos lenguajes es su flexibilidad y el
polimorfismo una de las herramientas que potencian esta cualidad. El
polimorfismo tiene un uso muy gráfico cuando hacemos uso de la
herencia.
El polimorfismo consiste en que toda referencia a un objeto de una clase
específica puede tomar la forma de una referencia a un objeto de una
clase heredada a la suya.

Con el polimorfismo (sig. Varias formas) se consigue que las instancias


de una clase padre puedan hacer uso de las funcionalidades de la clases
hijas: misma instancia que se comporta de varias (poli) maneras
(morfismo).
Ejemplo:
Public class Animal(){
public void habla(){
System.out.println("No se que soy");
}
}
Public class Perro() extends Animal{
public void() habla(){
System.out.println("Guau");
}
}
Public class Gato() extends Animal{
public void() habla(){
System.out.println("Miau");
}
}
Public class Zoo(){
public static void main(String[] args) {
Animal animal = new Gato(); animal. Habla(); animal=new Perro(); animal.
Habla();
}
}
El resultado por consola sera:
"Miau"
"Guau"

4.2 Clases abstractas definición, métodos


abstractos, implementación de clases
abstractas, modelado de clases abstractas
Clases abstractas
Concepto
Hay ocasiones, cuando se desarrolla una jerarquía de clases en que algún
comportamiento está presente en todas ellas pero se materializa de forma
distinta para cada una. Por ejemplo, pensemos en una estructura de clases
para manipular figuras geométricas. Podríamos pensar en tener una clase
genérica, que podría llamarse FiguraGeometrica y una serie de clases que
extienden a la anterior que podrían ser Circulo, Poligono, etc. Podría haber un
método dibujar dado que sobre todas las figuras puede llevarse a cabo esta
acción, pero las operaciones concretas para llevarla a cabo dependen del tipo
de figura en concreto (de su clase). Por otra parte la acción dibujar no tiene
sentido para la clase genérica FiguraGeometrica, porque esta clase
representa una abstracción del conjunto de figuras posibles.
Para resolver esta problemática Java proporciona las clases y métodos
abstractos. Un método abstracto es un método declarado en una clase para
el cual esa clase no proporciona la implementación (el código). Una clase
abstracta es una clase que tiene al menos un método abstracto. Una clase
que extiende a una clase abstracta debe implementar los métodos abstractos
(escribir el código) o bien volverlos a declarar como abstractos, con lo que ella
misma se convierte también en clase abstracta.

Declaración e implementación de métodos abstractos


Siguiendo con el ejemplo del apartado anterior, se puede escribir:
abstract class FiguraGeometrica {
abstract void dibujar();
}
class Circulo extends FiguraGeometrica {
void dibujar() {
// codigo para dibujar Circulo
}
}
La clase abstracta se declara simplemente con el modificador abstract en su
declaración. Los métodos abstractos se declaran también con el mismo
modificador, declarando el método pero sin implementarlo (sin el bloque de
código encerrado entre {}). La clase derivada se declara e implementa de
forma normal, como cualquier otra. Sin embargo si no declara e implementa
los métodos abstractos de la clase base (en el ejemplo el método dibujar) el
compilador genera un error indicando que no se han implementado todos los
métodos abstractos y que, o bien, se implementan, o bien se declara la clase
abstracta.

Referencias y objetos abstractos


Se pueden crear referencias a clases abstractas como cualquier otra. No hay
ningún problema en poner:
FiguraGeometrica figura;
Sin embargo una clase abstracta no se puede instanciar, es decir, no se
pueden crear objetos de una clase abstracta. El compilador producirá un error
si se intenta:
FiguraGeometrica figura = new FiguraGeometrica();
Esto es coherente dado que una clase abstracta no tiene completa su
implementación y encaja bien con la idea de que algo abstracto no puede
materializarse.
Sin embargo utilizando el up-casting visto en el capítulo dedicado a la
Herencia si se puede escribir:
FiguraGeometrica figura = new Circulo(. . .);
figura.dibujar();
La invocación al método dibujarse resolverá en tiempo de ejecución y la JVM
llamará al método de la clase adecuada. En nuestro ejemplo se llamará al
método dibujarde la clase Circulo
Código Fuente Musica2.java

import java.util.*;

abstract class Instrumento {


public abstract void tocar();
public String tipo() {
return "Instrumento";
}
public abstract void afinar();
}

class Guitarra extends Instrumento {


public void tocar() {
System.out.println("Guitarra.tocar()");
}
public String tipo() { return "Guitarra"; }
public void afinar() {}
}

class Piano extends Instrumento {


public void tocar() {
System.out.println("Piano.tocar()");
}
public String tipo() { return "Piano"; }
public void afinar() {}
}

class Saxofon extends Instrumento {


public void tocar() {
System.out.println("Saxofon.tocar()");
}
public String tipo() { return "Saxofon"; }
public void afinar() {}
}

// Un tipo de Guitarra
class Guzla extends Guitarra {
public void tocar() {
System.out.println("Guzla.tocar()");
}
public void afinar() {
System.out.println("Guzla.afinar()");
}
}

// Un tipo de Guitarra
class Ukelele extends Guitarra {
public void tocar() {
System.out.println("Ukelele.tocar()");
}
public String tipo() { return "Ukelele"; }
}

public class Musica2 {

// No importa el tipo de Instrumento,


// seguirá funcionando debido a Polimorfismo:
static void afinar(Instrumento i) {
// ...
i.tocar();
}

static void afinarTodo(Instrumento[] e) {

for(int i = 0; i < e.length; i++)


afinar(e[i]);
}

public static void main(String[] args) {


// Declarar un Arreglo SIN INSTANCIAS es valido en Clases Abstractas
Instrumento[] orquesta = new Instrumento[5];
// Generar una INSTANCIA de una la Clase Abstracta no es valido
// Instrumento nuevo = new Instrumento();
int i = 0;
// Up-casting al asignarse el Arreglo
orquesta[i++] = new Guitarra();
orquesta[i++] = new Piano();
orquesta[i++] = new Saxofon();
orquesta[i++] = new Guzla();
orquesta[i++] = new Ukelele();
afinarTodo(orquesta);
}
}

La Clase anterior es idéntica aquella definida en el ejemplo de Polimorfismo,


sin embargo, la Clase Base de Instrumento fue definida como abstract,
algunos detalles de esta definición:
· Nótese que los métodos definidos como abstract no contienen ningún
tipo de código dentro de ellos, inclusive no declaran ni llaves ({ }).
· Cuando es definido más de un método como abstract, es necesario que
la Clase como tal sea definida también como abstract.
La característica de hacer una Clase/Método abstract reside en que no puede
ser generada una instancia de la misma, este comportamiento se demuestra
en el método principal (main)
· Aunque dentro del método sea generado un Arreglo de esta Clase
abstracta, recuerde que un arreglo es únicamente un contenedor de Objetos,
esto permite que sea generado sin ningún error.
· Dentro de comentarios se encuentra la generación de
una instancia del tipo Instrumento la cual generaría un error al ser compilada
la Clase.

4.3 Reutilización del código


Lo primero que se les viene a la cabeza a los estudiantes (y a muchos
profesionales) cuando se les menciona la reutilización del código es el famoso
copiar y pegar al que se han acostumbrado en la programación estructurada, y de
hecho muchos lo hacen en poo, lo cual es una de las practicas que más encarece
el desarrollo de software. Como todo en Java, el problema se resuelve con las
clases. Para reutilizar el código creamos nuevas clases pero, en lugar de partir de
cero, partimos de clases, relacionadas con nuestra clase, que han sido ya creadas
y depuradas. El truco está en usar las clases sin ensuciar el código existente.

Una forma de hacer esto es crear objetos de nuestras clases existentes dentro de
la nueva clase. Esto se conoce como composición porque la nueva clase está
compuesta de objetos de clases existentes. Estamos reutilizando la funcionalidad
del código, y no la forma.

Otra forma es crear una nueva clase como un tipo de una clase ya existente.
Tomamos la forma de la clase existente y añadimos código a la nueva, sin
modificar la clase existente. Esta forma de crear nuevos objetos se llamada
herencia, y lo que hacemos es extender la clase en la que nos basamos para
crear la nueva.

Composición:
Hasta ahora hemos usado la composición de cierta manera, ej. cuando hacemos
una interfaz gráfica de usuario, nuestra clase de interfaz gráfica esta compuesta
por un frame, unos panel, botones, etc. todos estos objetos componen el objeto de
interfaz gráfica. Es decir que la composición consiste en poner manejadores de
objetos dentro de nuestra clase, estos manejadores de objetos no serán otra cosa
que instancias de las clases en las que nos estamos basando para crear la nueva
clase.
Recordemos que la forma para determinar cuándo usar composición es cuando
podemos decir que nuestra nueva clase “tiene un” elemento de otro tipo de
objetos, por ejemplo un cronómetro tiene: horas, minutos y segundos, es decir que
una clase Cronometro está compuesta por otras clases llamadas: Horas, Minutos
y Segundos.
Veamos como seria esta clase:
public class Cronometro {
Horas h;
Minutos m;
Segundos s;
String cadena;
int seg,min,hor;
public Cronometro() {
seg=0;
min=0;
hor=0;
h = new Horas();
m = new Minutos();
s = new Segundos();
cadena = new String("0 : 0 : 0");
}

public String avanzar(){


seg = s.forward();
if(seg==0){
min=m.forward();
if(min==0){
hor=h.forward();
}
}
cadena = hor + " : " + min + " : " + seg;
return cadena;
}
public String reset(){
seg = s.reset();
min = m.reset();
hor = h.reset();
cadena = hor + " : " + min + " : " + seg;
return cadena;
}
}
Nuestra clase Cronometro está compuesta entre otras cosas por objetos del tipo
Horas, Minutos y Segundos y a través del constructor de nuestra clase creamos
las instancias de cada una de ellas.
Herencia:
En java aunque no establezcamos de manera explícita la herencia siempre está
presente, ya que todas las clases que creemos heredan de la clase Object, por
eso es válido decir que en java todo es un objeto. La sintaxis para la composición
es obvia pero, para realizar la herencia, hay una forma claramente distinta.
Cuando heredamos, estamos diciendo "Esta nueva clase es como esa clase
antigua", por ejemplo es decir que la clase Horas “es una” UnidadDeTiempo.
Afirmamos esto en el código dando el nombre de la clase como siempre pero,
antes de la apertura del límite cuerpo de clase, pondremos la palabra clave
"extends" seguida por el nombre de la clase base. Cuando hagamos esto,
obtendremos automáticamente todos los datos miembros y métodos de la clase
base.

Primero veamos como seria la clase UnidadDeTiempo:

public class UnidadDeTiempo {


int valor;
int tope;
public int forward(){
if(valor == tope)
valor=0;
else
valor++;
return valor;
}

public int reset(){


valor=0;
return valor;
}
}

Y nuestra clase Horas:


public class Horas extends UnidadDeTiempo{
public Horas() {
this.valor=0;
this.tope=23;
}
}

De esta manera sin necesidad de tener que escribir nuevamente todos el código
de UnidadDeTiempo lo tememos disponible en la clase Horas, pero que partes
tenemos disponibles?, todos los atributos y los métodos de la clase padre están
disponibles en la clase hija pero dependiendo de los modificadores de acceso o
visibilidad de estos, por ejemplo los atributos y métodos de tipo friendly solo
estarán disponibles para las clases hijas que heredan de una clase padre en el
mismo paquete, los atributos y métodos de tipo public estarán disponibles para
todas las clases que hereden de la clase padre sin importar que se halle o no en el
mismo paquete; los miembros protected también son accesibles desde las clases
hijas.
El código de nuestra clases hijas no tienen porque limitarse solo al código
heredado, de hecho casi siempre la herencia se hace para extender la
funcionalidad de las clases heredadas añadiendo nuevos métodos y atributos.
La composición y la herencia:
Tanto la composición como la herencia permiten poner sub-objetos dentro de tu
nueva clase. Podríamos preguntarnos cuál es la diferencia entre los dos, y cuándo
elegir uno en lugar del otro. La composición es generalmente usada cuando
deseamos las características de una clase existente dentro de una nueva clase,
pero no su interfaz. Es decir, ponemos un para poder usarlo para implementar
características de nuestra nueva clase, pero el usuario de esa nueva clase verá el
interfaz que hemos definido en lugar del interfaz del objeto insertado.

Los objetos miembros usan la implementación ocultándose a sí mismos, por lo


que esto es una cosa segura a hacer y, cuando el usuario sabe que estamos
uniendo un conjunto de partes, hace que el interfaz sea más fácil de entender.
Cuando heredamos, estamos cogiendo una clase existente y creando una versión
especial de esa clase. En general, esto significa que estamos tomando una clase
de propósito general, especializándola para un caso o necesidad particular.
Pensando un poco, podrá entender que no tendría sentido construir un coche
usando un objeto vehículo (un coche no contiene un vehículo, ¡es un vehículo!). La
relación es- un viene expresada por la herencia, y la relación tiene un viene
expresada por la composición.

Conclusión
En esta investigación pudimos aprender sobre el uso de las clases abstractas y
cuál es su utilidad en la programación orientada a objetos, en la vida real no tiene
una utilidad ya que tiene una función no definida.

Bibliografías
https://sites.google.com/site/wwwprogramacionorientadacom/41-definicin

https://sites.google.com/site/wwwguiadeprogramacioncom/42-clases-abstractas-definicin-
mtodos-abstractos-implementacion-de-clases-abstractas-modelado-de-clases-abstractas

https://sites.google.com/site/wwwguiadeprogramacioncom/45-reutilizacion-del-cdigo

1.2.9 Técnicas de Reutilización de Código. (s. f.). cidecame. Recuperado 8


de mayo de 2021, de
http://cidecame.uaeh.edu.mx/lcc/mapa/PROYECTO/libro17/129_tcnicas_de
_reutili zacin_de_cdigo.html
B. (2015, 20 julio). Clases y miembros de clase abstractos y sellados: Guía
de programación de C#. Microsoft Docs.
https://docs.microsoft.com/eses/dotnet/csharp/programming-guide/classes-
and-structs/abstract-and-sealedclasses-and-class-members
Clase abstracta en C ++ | Implementación de Constructor con Ejemplo. (s. f.).
photo555. Recuperado 8 de mayo de 2021, de https://es.photo-
555.com/4718319abstract-class-in-c
Clases abstractas. (2012, 15 octubre). CPP.
https://inicioscpp.wordpress.com/clases-
abstractas/#:%7E:text=Las%20clases%20abstractas%20son%20%C3%BAtiles%2
0para%20definir%20interfaces%2C,clases%20abstractas%20se%20definen%20c
omo%20funciones%20virtuales%20puras.
Clases abstractas en programaciÃ3n orientada a objetos. (s. f.). informaticapc.
Recuperado 8 de mayo de 2021, de
https://informaticapc.com/poo/clasesabstractas.php#:%7E:text=Las%20clas
es%20abstractas

También podría gustarte