Programación Orientada a Objetos
ºConceptos generales:
La POO es una forma de programar que
trata de encontrar una solución a estos problemas. Introduce nuevos conceptos,
que superan y amplían conceptos antiguos ya conocidos. Entre ellos destacan los
siguientes:
Definiciones de las propiedades y comportamiento de un tipo de objeto
concreto. La instanciación es la lectura de estas definiciones y la creación de
un objeto a partir de ella.
Por ejemplo, herencia de la clase C a la clase D, es la facilidad mediante
la cual la clase D hereda en ella cada uno de los atributos y operaciones de C,
como si esos atributos y operaciones hubiesen sido definidos por la misma D.
Por lo tanto, puede usar los mismos métodos y variables registrados como
"públicos" (public) en C. Los componentes registrados como
"privados" (private) también se heredan pero se mantienen
escondidos al programador y sólo pueden ser accedidos a través de otros métodos
públicos. Para poder acceder a un atributo u operación de una clase en
cualquiera de sus subclases pero mantenerla oculta para otras clases es
necesario registrar los componentes como "protegidos" (protected),
de esta manera serán visibles en C y en D pero no en otras clases.
Instancia de una clase. Entidad provista de un conjunto de propiedades o
atributos (datos) y de comportamiento o funcionalidad (métodos), los mismos que
consecuentemente reaccionan a eventos. Se corresponden con los objetos reales
del mundo que nos rodea, o con objetos internos del sistema (del programa).
Algoritmo asociado a un objeto (o a una clase de objetos), cuya ejecución
se desencadena tras la recepción de un "mensaje". Desde el punto de
vista del comportamiento, es lo que el objeto puede hacer. Un método puede
producir un cambio en las propiedades del objeto, o la generación de un "evento"
con un nuevo mensaje para otro objeto del sistema.
Evento
Es un suceso en el sistema (tal como una interacción del usuario con la
máquina, o un mensaje enviado por un objeto). El sistema maneja el evento
enviando el mensaje adecuado al objeto pertinente. También se puede definir
como evento la reacción que puede desencadenar un objeto; es decir, la acción
que genera.
Atributos
Características que tiene la clase.
Mensaje
Una comunicación dirigida a un objeto, que le ordena que ejecute uno de sus
métodos con ciertos parámetros asociados al evento que lo generó.
Propiedad o atributo
Contenedor de un tipo de datos asociados a un objeto (o a una clase de
objetos), que hace los datos visibles desde fuera del objeto y esto se define
como sus características predeterminadas, y cuyo valor puede ser alterado por
la ejecución de algún método.
Estado interno
Es una variable que se declara privada, que puede ser únicamente accedida y
alterada por un método del objeto, y que se utiliza para indicar distintas
situaciones posibles para el objeto (o clase de objetos). No es visible al
programador que maneja una instancia de la clase.
Componentes de un objeto
Atributos, identidad, relaciones y métodos.
Identificación de un objeto
Un objeto se representa por medio de una tabla o entidad que esté compuesta
por sus atributos y funciones correspondientes.
En comparación con un lenguaje imperativo, una "variable" no es
más que un contenedor interno del atributo del objeto o de un estado interno,
así como la "función" es un procedimiento interno del método del
objeto.
ºClases y objetos:
La programación
orientada a objetos (POO) ofrece elementos que facilitan el desarrollo de
software en aspectos tales como modularización, reutilización de piezas de código (no copy/paste)
y encapsulamiento (ocultar el estado de los objetos)
Objetos:
Se puede decir que un objeto es todo
aquello que pueda ser identificable dentro de una especificación de
requerimientos o problema y tenga las siguiente características:
- Tenga estados definibles
(abierto, cerrado).
- Posea comportamientos asociados
(puede correr, saltar, volar, etc). Éstos son denominados métodos.
- Son capaces de
interactuar/comunicarse con otros objetos por medio de sus métodos
Una característica propia de este
paradigma, es la transparencia entre la implementación a nivel de código y la
funcionalidad que provee un método (no me interesa cómo lo haga, sólo que lo
haga).
Clases:
Las clases son plantillas que agrupan
comportamiento (métodos) y estados (atributos) de los futuros objetos.
Los objetos son instancias de una clase.
Usando el símil “variable – tipo” de la
programación estructurada, se entiendo que un objeto es una variable que tiene el comportamiento y estados
del tipo (objeto).
ºMetodos:
Los métodos de una
clase constituyen la lógica de la clase, es decir, contienen el código que
manipula el estado del objeto. Además constituyen el mecanismo utilizado para
implementar los mensajes entre objetos. Quiere decir, cuando un objeto se
comunica con otro por un mensaje lo hace por medio de la invocación al método
correspondiente del objeto. Y el mecanismo para invocar un método en java es
por medio de las referencias usando el operador de la siguiente forma:
referencia.metodo (parametros);
Declaración de los Métodos
Veamos la forma de declarar un
método. La estructura general de una declaración tiene dos partes, la
declaración y el cuerpo del método.
La Declaracion_del_metodo proporciona
información sobre su nombre, la accesibilidad del método, el número de
parámetros que recibe, etc. El Cuerpo_del_metodo contiene el conjunto
de sentencias que manipula los datos de cada objeto.
Sobrecarga de métodos
Cada método tiene una
"firma" por así decirlo, que son su nombre, el tipo y número de sus
parámetros. Existe una característica para tener dos métodos (ó constructores)
con el mismo nombre. Esta característica se denominasobrecarga de métodos.
Hemos estudiado la construcción
de distintos constructores para una clase y hemos puesto como ejemplo el caso
de una clase Publicacion. Veamos lo implementado hasta el momento y cómo
los constructores nos dan un ejemplo de sobrecarga de métodos:
El compilador resolverá que
constructor debe ejecutar en cada momento en función del número de parámetros y
su tipo. Si se llama al constructor sin parámetros se ejecutará el primer
constructor y en caso de hacerlo con dos parámetrosString se ejecutará el
segundo.
ºParametros y Argumentos:
Parámetros o argumentos
Objetivos:
a) Profundizar en el concepto de parámetro de
una clase e indicar su mecanismo de funcionamiento.
b) Interpretar el código fuente de una
aplicación Java donde aparecen parámetros de distintos tipos.
c) Construir una aplicación Java sencilla,
convenientemente especificada, que declare métodos con diferentes tipos de
parámetros.
Los
parámetros o argumentos son una forma de intercambiar información con el
método. Pueden servir para introducir datos para ejecutar el método (entrada) o
para obtener o modificar datos tras su ejecución (salida).
Declaración de parámetros: Los
parámetros se declaran en la cabecera de la declaración de los métodos. Al
declararse el parámetro, se indica el tipo de dato y el identificador
correspondiente. Los parámetros o argumentos de un constructor o de un método
pueden ser de cualquier tipo, ya sean tipos primitivos o referencias de objetos
(en este caso debe indicarse el identificador de la clase correspondiente).
ºRetorno de valores:
Métodos con
retorno
Un método
vuelve al código del que se llamó en el momento en el que alguna de estas
circunstancias se de:
- se
completan todas las sentencias del método,
- llega a
una sentencia retorno o
- lanza
una excepción,
El tipo
de retorno de un método se especifica en la declaración del método. Dentro del
cuerpo del método, se utiliza la sentencia return para devolver el valor.
Cualquier
método que esté declarado como void, no devolverá ningún valor.
Si se
intenta devolver un valor desde un método declarado void, aparecerá un error de
compilación.
Cualquier
método que no sea declarado void, deberá contener una sentencia return con su
correspondiente valor de retorno;
return valorRetorno;
El tipo de dato del valor
de retorno deberá coincidir con el tipo de retorno de la declaración del
método. No se puede retornar un valor integer, a un método en el que en su
declaración aparece como valor de retorno, un boolean.
package com.edu4java.Tutorial11;
import java.util.Scanner;
public class Tutorial11 {
public static void main(String[] args) {
int[] array = new int[5];
Scanner scanner = new Scanner(System.in);
insertarDatosArray(array, scanner);
sumarArray(array);
int max = maxArray(array);
System.out.println("Max= " + max);
double promedio = promedioArray(array);
System.out.println("Promedio= " + promedio);
}
private static void insertarDatosArray(int[] array, Scanner scanner) {
for (int i = 0; i < array.length; i++) {
System.out.print("insertar array[" + i + "]:");
array[i] = scanner.nextInt();
}
}
private static void sumarArray(int[] array) {
System.out.print("Suma: ");
int acumulador = 0;
for (int i = 0; i < array.length; i++) {
acumulador = acumulador + array[i];
System.out.print("+" + array[i]);
}
System.out.println("= " + acumulador);
}
private static int maxArray(int[] array) {
int max = 0;
for (int i = 0; i < array.length; i++) {
if (array[i] > max) {
max = array[i];
}
}
return max;
}
private static double promedioArray(int[] array) {
double promedio = 0;
for (int i = 0; i < array.length; i++) {
promedio = promedio + array[i];
}
promedio = promedio / array.length;
return promedio;
}
}
ºMetodo
Constructor:
En programación orientada a objetos (POO),
un constructor es
una subrutina cuya
misión es inicializar un objeto de una clase. En el constructor se asignan los valores
iniciales del nuevo objeto.
Se utiliza para crear tablas de clases virtuales y poder así desarrollar
el polimorfismo, una
de las herramientas de la programación orientada a objetos. Al utilizar un
constructor, el compilador determina cual de los objetos va a responder
al mensaje (virtual) que hemos creado. Tiene un tipo de acceso, un nombre y un
paréntesis.
En Java es un método especial dentro de
una clase, que se llama automáticamente cada vez
que se crea un objeto de esa clase.
Posee el mismo nombre de la clase a la cual pertenece
y no puede devolver ningún valor (ni siquiera se puede especificar la palabra
reservada void). Por ejemplo, si añadiéramos a la
clase SSuma un constructor, tendríamos que
llamarlo también SSuma. Cuando en una clase no se escribe propiamente un
constructor, Java asume uno por defecto.
Ejemplo
Un constructor por defecto para la clase SSuma quedaría así:
public SSuma() {}
Como se observa el constructor no posee ningún
parámetro, ya que como no ha sido definido propiamente por el programador, Java
lo hace por default.
Si se define un constructor con parámetros (definido
explícitamente) el constructor por default se reemplaza por
este.
A continuación se creará un constructor explícito para
una clase simple, utilizando una clase Persona con una serie de atributos.
Primero se declara la clase con sus atributos:
class Persona
{
//ATRIBUTOS
private String nombre;
private int edad;
private String empleo;
private double salario;
//CONSTRUCTORES
public Persona() {} //CONSTRUCTOR SIN PARÁMETROS
public Persona(String nombre, int edad, String empleo, double salario)
{
asignarNombre(nombre);
asignarEdad(edad);
asignarEmpleo(empleo);
asignarSalario(salario);
}
//...
}
El constructor sin parámetros es reemplazado por el
constructor explícito. En este ejemplo se puede observar que los constructores
preferentemente se declaran públicos para que puedan ser invocados desde
cualquier parte.
Una línea como esta invocará al constructor sin
parámetros:
Persona pers01 = new Persona();// invoca al constructor Persona
El operador new crea un nuevo
objeto, en este caso de la clase Persona, y a continuación se
invoca al constructor de la clase para realizar las operaciones de iniciación
que estén programadas.
A continuación se invocará al constructor con
parámetros, que se introducirán en el orden especificado en el constructor.
Persona pers02 = new Persona("Pepe Pérez", 30, "Programador", 25000);
ºSobrecarga de Metodos:
Sobrecarga es la capacidad de un lenguaje de programación, que permite nombrar
con el mismo identificador diferentes variables u operaciones.
En programación orientada a objetos la
sobrecarga se refiere a la posibilidad de tener dos o más funciones con el mismo nombre pero
funcionalidad diferente. Es decir, dos o más funciones con el mismo nombre
realizan acciones diferentes. El compilador usará
una u otra dependiendo de los parámetros usados. A esto se llama
también sobrecarga de funciones.
También existe la sobrecarga de operadores que al
igual que con la sobrecarga de funciones se le da más de una implementación a
un operador.
El mismo método dentro de una clase permite hacer
cosas distintas en función de los parámetros.
Java no permite al programador implementar sus propios
operadores sobrecargados, pero sí utilizar los predefinidos como el +. C++, por
el contrario si permite hacerlo
Ejemplo:
public class Articulo {
private float precio;
public void setPrecio() {
precio = 0;
}
public void setPrecio(float nuevoPrecio) {
precio = nuevoPrecio;
}
}
Diferencias
En el caso anterior, el método setPrecio tiene diferentes tipos de entrada
de parámetros, en el primer caso este no acepta valores de entrada y en el
segundo este acepta un valor de tipo float.
Ejemplo
Tenemos un método que soporta varios tipos de parámetros, entonces cuando
hacemos uso de este, lo que hace el compilador es buscar el que posee ese tipo
de parámetros
Color (int r, int g, int b)
Color (float a, float b, float c)
//--------------------------------------------
//r,g,b (son valores enteros entre 0 y 255)
//a,b,c (son valores flotantes entre 0.0 y 1.0)
Entonces cuando hacemos una llamada a
este método (en este caso sería un constructor), el compilador hace referencia
al tipo de parámetros. La sobrecarga sería redefinir cualquiera de estos
métodos utilizando los mismos parámetros pero para un proceso distinto.
ºModificadores
de Acceso:
Todos los tipos y miembros de tipo
tienen un nivel de accesibilidad que controla si se pueden usar desde otro
código del ensamblado u otros ensamblados. Puede usar los siguientes
modificadores de acceso para especificar la accesibilidad de un tipo o miembro
cuando lo declare:
public:
Puede obtener acceso al tipo o miembro cualquier otro código del mismo ensamblado o de otro ensamblado que haga referencia a éste.
Puede obtener acceso al tipo o miembro cualquier otro código del mismo ensamblado o de otro ensamblado que haga referencia a éste.
private:
Solamente el código de la misma clase o estructura puede acceder al tipo o miembro.
Solamente el código de la misma clase o estructura puede acceder al tipo o miembro.
protected:
Solamente el código de la misma clase o estructura, o de una clase derivada de esa clase, puede acceder al tipo o miembro.
Solamente el código de la misma clase o estructura, o de una clase derivada de esa clase, puede acceder al tipo o miembro.
internal:
Puede obtener acceso al tipo o miembro cualquier código del mismo ensamblado, pero no de un ensamblado distinto.
Cualquier código del ensamblado en el que se ha declarado, o desde cualquier clase derivada de otro ensamblado, puede acceder al tipo o miembro. El acceso desde otro ensamblado debe producirse en una declaración de clase que derive de la clase en la que se haya declarado el elemento interno protegido y se debe realizar mediante una instancia del tipo de clase derivada.
Puede obtener acceso al tipo o miembro cualquier código del mismo ensamblado, pero no de un ensamblado distinto.
Cualquier código del ensamblado en el que se ha declarado, o desde cualquier clase derivada de otro ensamblado, puede acceder al tipo o miembro. El acceso desde otro ensamblado debe producirse en una declaración de clase que derive de la clase en la que se haya declarado el elemento interno protegido y se debe realizar mediante una instancia del tipo de clase derivada.
En los ejemplos siguientes se muestra
cómo especificar modificadores de acceso en un tipo y miembro:
public class Bicycle
{
public void Pedal() { }
}
No todos los tipos o miembros pueden
usar todos los modificadores de acceso en todos los contextos; en algunos casos
la accesibilidad de un miembro de tipo está restringida por la accesibilidad de
su tipo contenedor. En las secciones siguientes se proporcionan más detalles
sobre la accesibilidad.
ºEncapsulamiento y métodos accesores:
En programación modular, y más específicamente
en programación orientada a objetos, se
denomina encapsulamiento al ocultamiento del estado, es decir,
de los datos miembro de un objeto de manera que solo se pueda cambiar mediante
las operaciones definidas para ese objeto.
Cada objeto está aislado
del exterior, es un módulo natural, y la aplicación entera se reduce a un
agregado o rompecabezas de objetos. El aislamiento protege a los datos
asociados de un objeto contra su modificación por quien no tenga derecho a
acceder a ellos, eliminando efectos secundarios e interacciones.
De esta forma el usuario de la clase puede obviar la
implementación de los métodos y propiedades para concentrarse solo en cómo
usarlos. Por otro lado se evita que el usuario pueda cambiar su estado de
maneras imprevistas e incontroladas.
Como se
puede observar de los diagramas las variables del objeto se localizan en el
núcleo del objeto. Los métodos rodean y esconden el núcleo del objeto de otros
objetos en el programa. Al empaquetamiento de las variables de un objeto con la
protección de sus métodos se le llama encapsulamiento. Típicamente, el
encapsulamiento es utilizado para esconder detalles de la puesta en práctica no
importantes de otros objetos. Entonces, los detalles de la puesta en práctica
pueden cambiar en cualquier tiempo sin afectar otras partes del programa.
ºConstantes:
En programación,
una constante es un valor que no puede ser alterado/modificado durante la
ejecución de un programa, únicamente puede ser leído.
Una constante corresponde a una longitud
fija de un área reservada en la memoria principal del ordenador, donde el
programa almacena valores fijos.
Por ejemplo:
·
El valor de PI = 3,1416
C
En C las
constantes se declaran con la directiva #define, esto significa que
esa constante tendrá el mismo valor a lo largo de todo el programa.
El identificador de una constante así definida será una cadena
de caracteres que deberá cumplir los mismos requisitos que el de una variable
(sin espacios en blanco, no empezar por un dígito numérico, etc).
Ejemplo:
#include <stdio.h>
#define PI 3.1415926
int main()
{
printf("Pi vale %f", PI);
return 0;
}
Lo cual mostrará por pantalla:
Pi vale 3.1415926
Es decir, PI es una constante a la que le hemos
asignado el valor 3,1415926 mediante la directiva #define.
La directiva #define también se puede utilizar
para definir expresiones más elaboradas con operadores (suma, resta,
multiplicación etc) y otras constantes que hayan sido definidas previamente,
por ejemplo:
#define X 2.4
#define Y 9.2
#define Z X + Y
C++
En C++ el uso de #define
esta totalmente desaconsejado, para declarar una constante simbólica
(equivalente a constante en C) se usa la palabra clave const seguido del tipo
de dato que queramos incluir.
Pascal
En el lenguaje de
programación Pascal es
posible declarar constantes de cualquier tipo de dato utilizando (al igual
que C++) la palabra reservada const.
Const Saludar = "Hola Wiki-Informaticos!"
En este lenguaje, las constantes pueden ser establecidas en
parámetros de cualquier tipo (cadena o numéricos) sin presentar errores y al
igual que en C se
permite que las constantes realicen cálculos antes de ser utilizadas.
ºMiembros estaticos:
Para definir una propiedad o método estático en lenguaje Java se
antepone el modificador static a
su nombre.
Las propiedades estáticas de una Clase son compartidas por todos los
Objetos que heredan de ella, con lo que si su valor es modificado en cualquier
de ellos afectará a todas las demás instancias.
El mencionado modificador static es
utilizado también para declarar constantes o propiedades cuyo
valor no puede ser modificado una vez definido.
Por otro lado, para acceder a los métodos estáticos de
una clase no es necesario crear un objeto, pudiendo acceder a ellos a través
del propio nombre de clase.
A continuación te mostramos un ejemplo
práctico que te ayudará a aprender cómo se implementa todo lo que te acabamos
de comentar.
ºHerencia
En ciertos lenguajes, el diseñador puede
definir qué variables de instancia y métodos de los objetos de una clase son
visibles. En C++ y java esto se consigue con las especificaciones private, protected y public.
Sólo las variables y métodos definidos como públicos en un objeto serán
visibles por todos los objetos. En otros lenguajes como Smalltalk, todas las
variables de instancia son privadas y todos los métodos son públicos.
Dependiendo del lenguaje que se utilice,
el diseñador también puede controlar qué miembros de las superclases son
visibles en las subclases. En el caso de java y C++ los especificadores de
acceso (private, protected, public) de los miembros de la superclase afectan
también a la herencia:
Private
Ningún miembro privado de la superclase es visible en la subclase.
Protected
Los miembros protegidos de la superclase son visibles en la subclase, pero
no visibles para el exterior.
Public
Los miembros públicos de la superclase siguen siendo públicos en la
subclase.
import javax.*;
import javax.swing.JOptionPane;
public class Mamifero{
private int patas;
private String nombre;
public void imprimirPatas(){
JOptionPane.showMessageDialog(null," Tiene
" + patas + " patas\n", "Mamifero", JOptionPane.INFORMATION_MESSAGE);
}
public Mamifero(String nombre, int patas){
this.nombre = nombre;
this.patas = patas;
}
}
public class Perro extends Mamifero {
public Perro(String nombre){
super(nombre, 4);
}
}
public class Gato extends Mamifero {
public Gato(String nombre){
super(nombre, 4);
}
}
public class CrearPerro {
public static void main(String[] args) {
Perro perrito = new Perro("Pantaleon");
perrito.imprimirPatas(); /*Está en la clase mamífero*/
}
}
Se declaran las clases mamíferos, gato y
perro, haciendo que gato y perro sean unos mamíferos
(derivados de esta clase), y se ve como a través de ellos se nombra al animal
pero así también se accede a patas dándole el valor por defecto para esa
especie.
Es importante destacar tres cosas. La primera,
es que la herencia no es un mecanismo esencial en el paradigma de programación
orientada a objetos; en la mayoría de los lenguajes orientados a objetos
basados en prototipos las clases no existen, en consecuencia tampoco existe la
herencia y el polimorfismo se logra por otros medios. La segunda, es que el
medio preferido para lograr los objetivos de extensibilidad y reutilización es
la agregación o composición. La tercera, es que en lenguajes con un sistema de
tipos débiles, el polimorfismo se puede lograr sin utilizar la herencia.
Por otra parte y aunque la herencia no
es un concepto indispensable en el paradigma de programación orientada a
objetos, es mucho más que un mecanismo de los lenguajes basados en clases,
porque implica una forma de razonar sobre cómo diseñar ciertas partes de un
programa. Es decir, no sólo es un mecanismo que permite implementar un diseño,
sino que establece un marco conceptual que permite razonar sobre cómo crear ese
diseño.
ºSobreescritura de
Métodos
Una subclase hereda todos los métodos de su superclase que son accesibles a
dicha subclase a menos que la subclase sobreescriba los métodos.
Una subclase sobreescribe un método de su superclase cuando define un método con las mismas características ( nombre, número y tipo de argumentos) que el método de la superclase.
Las subclases emplean la sobreescritura de métodos la mayoría de las veces para agregar o modificar la funcionalidad del método heredado de la clase padre.
Una subclase sobreescribe un método de su superclase cuando define un método con las mismas características ( nombre, número y tipo de argumentos) que el método de la superclase.
Las subclases emplean la sobreescritura de métodos la mayoría de las veces para agregar o modificar la funcionalidad del método heredado de la clase padre.
Ejemplo
class ClaseA
{
void miMetodo(int var1, int var2)
{ ... }
String miOtroMetodo( )
{ ... }
}
class ClaseB extends ClaseA
{
/* Estos métodos sobreescriben a los métodos
de la clase padre */
void miMetodo (int var1 ,int var2)
{ ... }
String miOtroMetodo( )
{ ... }
}
ºClases y métodos abstractos:
El sentido está en que una superclase permite
unificar campos y métodos de las subclases, evitando la repetición de código y
unificando procesos. Ahora bien, una clase de la que no se tiene intención de
crear objetos, sino que únicamente sirve para unificar datos u operaciones de
subclases, puede declararse de forma especial en Java: como clase abstracta. La
declaración de que una clase es abstracta se hace con la sintaxis public
abstract class NombreDeLaClase { … }. Por ejemplo public
abstract class Profesor. Cuando utilizamos esta sintaxis, no resulta
posible instanciar la clase, es decir, no resulta posible crear objetos de ese
tipo. Sin embargo, sigue funcionando como superclase de forma similar a como lo
haría una superclase “normal”. La diferencia principal radica en que no se
pueden crear objetos de esta clase.
Declarar una clase abstracta es distinto a tener una
clase de la que no se crean objetos. En una clase abstracta, no existe la
posibilidad. En una clase normal, existe la posibilidad de crearlos aunque no
lo hagamos. El hecho de que no creemos instancias de una clase no es suficiente
para que Java considere que una clase es abstracta. Para lograr esto hemos de
declarar explícitamente la clase como abstracta mediante la sintaxis que hemos
indicado. Si una clase no se declara usando abstract se cataloga como “clase
concreta”. En inglés abstract significa “resumen”, por eso en algunos textos en
castellano a las clases abstractas se les llama resúmenes. Una clase abstracta
para Java es una clase de la que nunca se van a crear instancias: simplemente
va a servir como superclase a otras clases. No se puede usar la palabra
clave new aplicada a clases abstractas. En el menú contextual
de la clase en BlueJ simplemente no aparece, y si intentamos crear objetos en
el código nos saltará un error.
A su vez, las clases abstractas suelen contener
métodos abstractos: la situación es la misma. Para que un método se considere
abstracto ha de incluir en su signatura la palabra clave abstract. Además un
método abstracto tiene estas peculiaridades:
a) No tiene cuerpo (llaves): sólo
consta de signatura con paréntesis.
b) Su signatura termina con un punto y coma.
c) Sólo puede existir dentro de una clase
abstracta. De esta forma se evita que haya métodos que no se puedan
ejecutar dentro de clases concretas. Visto de otra manera, si una clase incluye
un método abstracto, forzosamente la clase será una clase abstracta.
d) Los métodos abstractos forzosamente habrán
de estar sobreescritos en las subclases. Si una subclase no
implementa un método abstracto de la superclase tiene un método no ejecutable,
lo que la fuerza a ser una subclase abstracta. Para que la subclase sea
concreta habrá de implementar métodos sobreescritos para todos los métodos abstractos
de sus superclases.
Un método abstracto para Java es un método que nunca
va a ser ejecutado porque no tiene cuerpo. Simplemente, un método abstracto
referencia a otros métodos de las subclases. ¿Qué utilidad tiene un método
abstracto? Podemos ver un método abstracto como una palanca que fuerza dos
cosas: la primera, que no se puedan crear objetos de una clase. La segunda, que
todas las subclases sobreescriban el método declarado como abstracto.
Sintaxis tipo: abstract public/private/protected TipodeRetorno/void (
parámetros … );
Por ejemplo: abstract
public void generarNomina (int diasCotizados, boolean plusAntiguedad);
ºPolimorfismo:
En programación orientada a objetos, el polimorfismo o poliformismo se
refiere a la propiedad por la que es posible enviar mensajes sintácticamente
iguales a objetos de tipos distintos.
El único requisito que deben cumplir los objetos que se utilizan de manera
polimórfica es saber responder al mensaje que se les envía.
La apariencia del código puede ser muy diferente
dependiendo del lenguaje que se utilice, más allá de las obvias diferencias
sintácticas.
Por ejemplo, en un lenguaje de programación que cuenta
con un sistema de tipos dinámico (en los que las
variables pueden contener datos de cualquier tipo u objetos de cualquier clase)
como Smalltalk se
requiere que los objetos que se utilizan de modo polimórfico sean parte de una
jerarquía de clases.
EJEMPLO:
En el siguiente ejemplo
hacemos uso del lenguaje C++ para ilustrar el polimorfismo. Se observa a la vez
el uso de las funciones virtuales puras, como se les conoce en C++, estas
funciones constituyen una interfaz más consistente cuando se trabaja con una
jerarquía de clases, puesto que hacen posible el enlace durante la ejecución.
Sin embargo como se verá, para que el polimorfismo funcione no es una condición
obligatoria que todas las funciones en la clase base sean declaradas como
virtuales.
#include<iostream>
#include <math.h>
using namespace std;
class Figura {
private:
float base;
float altura;
public:
void captura();
virtual unsigned float perimetro()=0;
virtual unsigned float area()=0;
};
class Rectangulo: public Figura {
public:
void imprime();
unsigned float perimetro(){return 2*(base+altura);}
unsigned float area(){return base*altura;}
};
class Triangulo: public Figura {
public:
void muestra();
unsigned float perimetro(){return 2*sqrt(altura^2+(base/2)^2)+base;} //Usando pitágoras
unsigned float area(){return (base*altura)/2;}
};
void Figura::captura()
{
cout << "CALCULO DEL AREA Y PERIMETRO DE UN TRIANGULO ISÓSCELES Y UN RECTANGULO:" << endl;
cout << "escribe la altura: ";
cin >> altura;
cout << "escribe la base: ";
cin >> base;
cout << "EL PERIMETRO ES: " << perimetro();
cout << "EL AREA ES: " << area();
getchar();
return 0;
}
Comentarios
Publicar un comentario