Lenguaje Java 
Introducción
Se puede decir que Java es mucho más que un Lenguaje Orientado a Objetos, es una plataforma de desarrollo multiplataforma.
Sin embargo aquí nos interesa Java como Lenguaje de Programación Orientado a Objetos (POO) y Netbeans como el entorno de desarrollo integrado (IDE) que nos permitirá desarrollar programas en Java.
Así pues nos enfocaremos en siguientes temas:
- ¿Qué es la POO y cómo se diferencia de la Programación Procedimental?
- Nos centraremos sobre ciertas características de Java como Lenguaje de Programación Orientado a Objetos
Tendríamos que poder hallar respuesta a las siguientes preguntas:
- ¿Qué tipos de datos básicos tiene el lenguaje Java?
- ¿Qué son las clases y qué son los objetos?
- ¿Qué es el ámbito y cómo juega en ello la palabra reservada this?
- ¿Qué son y para qué sirven los calificadores de acceso?
- ¿Qué tipos de Estructuras Alternativas y Repetitivas encontramos en Java?
Java y la POO - Diferencia con la Programacion Estructurada
La programación orientada a objetos (POO) es un paradigma de programación que enfoca el desarrollo de aplicaciones de manera integral.
A diferencia de la programación procedimental, en la programación orientada a objetos se gestionan los atributos y métodos de un objeto en forma conjunta y atómica. Un objeto considera ambos aspectos como fundamentales y los trata en conjunto, es decir, los atributos y métodos del objeto están diseñados para trabajar en conjunto en una plantilla llamada clase.
Cuando se ejecuta el programa, se instancia al objeto definido en la plantilla.
En cambio, en la programación procedimental, los procedimientos y funciones están separados de los atributos, es decir de los ‘objetos’ que gestionan, y todo el sistema se controla mediante los mismos. Esto quiere decir que las funciones y procedimientos tienen preeminencia sobre los datos; o que los datos se suelen tratar en forma independiente del proceso, en cierto modo restándole importancia, y focalizando en realidad todo el esfuerzo en el proceso.
Postulados de la POO
La POO se basa en algunos postulados, que también la diferencian de la programación estructurada, siendo los más importantes los siguientes:
- Abstracción: se definen las características esenciales del objeto (tanto atributos como comportamiento)
- Encapsulamiento: todos los elementos de una misma entidad están al mismo nivel de abstracción
- Aislamiento: los objetos están aislados del entorno o contexto que los rodea, lo que permite proteger sus atributos y métodos
- Modularidad: es más fácil dividir una aplicación grande en componentes debido a que unos objetos se pueden ensamblar unos con otros, ya que se comunican mediante mensajes;
- Herencia: significa en concreto que una clase hija heredará todos los atributos y métodos de la clase padre.
- Polimorfismo: el significado obvio de esta palabra es "varias formas" y quiere decir que un objeto puede tener métodos con el mimo nombre que otros objetos diferentes y no interferirán entre sí; por ejemplo.
- Recolección de basura: es una característica importante y que en los hechos significa que aquél objeto que no es utiliza se destruye.
Clase y Objeto
Es muy importante comprender estos dos conceptos:
- CLASE: es un modelo o plantilla para representar un objeto.
- OBJETO: es una ENTIDAD, es decir, es algo concreto obtenido de la plantilla.
Entonces una CLASE es el molde básico para luego crear los objetos.
Una clase se define con atributos y métodos. Los atributos son las propiedades que van a caracterizar al objeto en forma general y los métodos son las funciones u operaciones que van a poder realizar el objeto.
Por lo tanto también podemos decir que una CLASE es una abstracción de un objeto.
Todo objeto tiene las siguentes características:
- cuenta con una identidad es decir se diferencia de otros objetos a través de uno o más valores que lo identifican como tal;
- tiene un estado que viene dado o determinado por los datos del objet (del conjunto de valores de sus atibutos);
- y tiene un comportamiento que viene dado o depende de sus métodos.
A continuación veremos un ejemplo sencillo de modo tal de comprender estos conceptos.
Crearemos una plantilla o clase llamada Persona, con tres atributos básicos solamente: dni, apellido y nombre.
Ulizamos Netbeans por ser un IDE muy bien integrado con Sistemas de Bases de Datos. Así pues lo primero que tendríamos que hacer es crear el Proyecto Persona y en la carpeta sources crear la clase Persona.java:
package Persona;
public class Persona {
//atributos
private int DNI;
private String Nombre;
private String Apellido;
//constructor
public Persona(int d,String nom, String ape){
this.DNI=d;
this.Nombre=nom;
this.Apellido=ape;
}
//métodos
public int getDni(){ return this.DNI;}
public String getApellido(){return this.Apellido;}
public String getNombre(){return this.Nombre;}
public String mostrarDatos(){
String cadena="Los datos de la Persona son: \n"
+ "DNI: " + this.getDni() + "\n"
+ "Apellido: "+ this.getApellido() + "\n"
+ "Nombre: " +this.getNombre();
return cadena;
}
}//fin clase Persona
Esta plantilla no se ejecutará, es sólo una clase o plantilla, pero podemos crear el objeto utilizando un archivo Java que sea el runtime y use a esta plantilla.
El código que inicie el objeto podría estar en el mismo archivo o bien en otro archivo, que es lo más apropiado puesto que así aprovechamos tambén la modularidad de Java.
Para eso vamos a usar una clase aparte, una clase runtime. Es importante tener en cuenta que ambos archivos deben formar o ser parte del mismo paquete (el mismo directorio o carpeta digamos)
El runtime será el archivo crearPersona.java:
package Persona;
public class crearPersona {
//método instanciador o runtime
public static void main(String[] args) {
Persona Pedro = new Persona(45600353,"Pedro","Ramirez");
System.out.println(Pedro.mostrarDatos());
}
}//fin clase crearPersona
En la clase runtime se puede apreciar que la clase Persona es en definitiva un tipo de datos definido por el usuario ya que la variable Pedro es de tipo Persona.
En ambas clases hemos resaltado partes del código con colores para diferenciar conceptos. Por ejemplo tanto las clases como los atributos y métodos se ven afectados por los calificadores de acceso (public y private en el código). Estos calificadores permiten cumplir con el postulado de aislamiento y con el muy importante de contexto (palabra reservada this).
Todo esto se verá en detalle más adelante, pero es necesario primero empezar por el principio.
En los siguientes videos se muestra la arquitectura anterior:
1. Utilizando Netbeans IDE
2. Utilizando la consola de Linux Mint
Los siguientes links sirven para conocer los comandos de la Terminal:
El lenguaje Java
Tipos de Datos en Java
Java es un lenguaje fuertemente tipeado, esto quiere decir, que las variable siempre tienen que estar declaradas antes de poder usarlas lo cual implica establecer el nombre y tipo de variable:
int ruedas=2;
Java cuenta con 8 tipos primitivos de datos, a saber:
- byte
- short
- int
- long
- float
- double
- boolean
- char
Además de estos tipos de datos primitivos cuenta con soporte para cadenas mediante la clase String, que si bien no es un tipo de datos primitivo podría considerarse como tal.
Para consultar y saber más ver: https://docs.oracle.com/javase/tutorial/java/nutsandbolts/datatypes.html
Valores por defecto:
Como sabemos no siempre es necesario asignar un valor cuando se declara una variable, ya que puede ser declarada y no inicializada hasta el momento de utilizarse, sin embargo no es considerada un buena técnica de programación. Por lo tanto es bueno conocer cuáles son los valores básicos o por defecto de inicialización:
Tipo de Datos | Valor por defecto de inicialización |
---|---|
byte | 0 |
short | 0 |
int | 0 |
long | 0L |
float | 0.0f |
double | 0.0d |
char | '\u0000' |
String (o cualquier otro objeto) | null |
boolean | false |
Java, como otros lenguajes, también usa literales o constantes; es decir, valores fijos o que no cambian.
Arreglos: (en elaboración)
Por el momento, ver en https://docs.oracle.com/javase/tutorial/java/nutsandbolts/arrays.html
Operadores Java y precedencias
Operadores | Precedencia |
---|---|
Postfix | expr++ expr-- |
Unario | ++expr --expr +expr -expr ~ ! |
Multiplicación | * / % |
Adición | + - |
Shift | << >> >>> |
Relacionales | < > <= >= instanceof |
Igualdad | == != |
bitwise AND | & |
bitwise exclusive OR | ^ |
bitwise inclusive OR | | |
AND lógico | && |
OR lógico | || |
Ternario | ? : |
Asignación | = += -= *= /= %= &= ^= |= <= >>= >>>= |
Ver más en https://docs.oracle.com/javase/tutorial/java/nutsandbolts/operators.html
Sentencias de Control de Flujo
Java permite controlar el flujo del programa mediante estructuras Alternativas y Repetitivas, y lógicamente estructuras anidadas de las anteriores.
Encararemos el estudio de dichas estructura como lo vemos en Programación I(tercer año) de la Escuela; es decir, especificando la sintaxis algorítmica en español. Sin embargo se puede consultar el Tutorial Java
Estructuras Alternativas
Este tipo de estructuras se utiliza cuando debido a alguna condición hay acciones que implican una ruptura en la secuencia. Estas estructuras pueden ser de 3 tipos:
- Estructura alternativa simple
- Estructura alternativa doble
- Estructura alternativa múltiple o Selectiva
En Recursos / Videos se pueden ver ejemplos de estas estructuras así como descargar los proyectos fuentes.
1. Estructura Alternativa Simple
Son aquellas en las cuales sólo se realizan acciones cuando se cumple la condición; es decir, sólo si la condición es verdadera, entonces se ingresa en la estructura alternativa.
La sintaxis general es la siguiente:
Inicio
Acción
Acción
Acción
SI condición entonces
Acción
Acción
Acción
FIN SI
Fin
En Java la sintaxis es:
if( condición) {
Acción
Acción
Acción
}
O sea, las llaves { } determinan el inicio y fin de la estructura alternativa; es decir son equivalentes al entonces y al FIN SI de nuestra sintaxis algorítmica.
2. Estructura Alternativa Doble
Esta estructura es similar a la anterior, la única diferencia es que las acciones se ejecutarán no sólo si se cumple la condición sino que otras acciones se ejecutan cuando la condición no se cumpla; es decir, tant si la condición es verdadera (se cumple) como falsa (no se cumple) se llevarán a cabo acciones específicas.
La estructura tiene la siguiente sintaxis
Inicio
Acción
Acción
Acción
SI condición entonces
Acción
Acción
Acción
SINO
Acción
Acción
Acción
FIN SI
Fin
En Java la sintaxis es:
if( condición) {
Acción
Acción
Acción
}
else {
Acción
Acción
Acción
}
}
Cuando en los bloques condicionales hay una sóla acción, en Java se pueden evitar los parénteis.
Tomando como ejemplo el ejercicio que se puede descargar:
if (numero == 0)
System.out.println("El número "+numero+" es nulo");
else
if (numero >0)
System.out.println("El número "+numero+" es positivo");
else
System.out.println("El número "+numero+" es negativo");
3. Estructura Alternativa Múltiple o Selectiva
Esta estructura se utiliza en lugar de utilizar múltiples alternativas porque es más claro el código y la probabilidad de cometer errores. Para utilizar esta estructura es necesario contar con una variable que permita indentificar el grupo de acciones a llevar acabo; es decir, esta variable tomará un valor u otro y es importante que no sea ambiguo.
La estructura tiene la siguiente sintaxis:
Inicio
Acción
Acción
Acción
SEGUN CASO variable hacer
CASO A
Acción
Acción
Acción
CASO B
Acción
Acción
Acción
CASO N
Acción
Acción
Acción
OTRO CASO
Acción
Acción
Acción
FIN SEGUN CASO
Fin
Una implementación de la Estructura Selectiva puede verse en el ejemplo Anidadas.zip que está disponible para su descarga.
Estructuras Repetitivas
Estas estructuras también se usan cuando es necesario repetir las acciones una serie de veces, conocidas o no. Estas estructuras pueden ser de 3 tipos:
- Estructura Repetir
- Estructura Mientras
- Estructura Para
En Recursos / Videos se pueden ver ejemplos de estas estructuras repetitivas así como descargar los proyectos fuentes.
1. Repetir
Esta estructura también es conocida como CICLO 1 puesto que siempre se ejecuta una vez ya que la condición se evalúa al final. La sintaxis algorítmica es más complicada que las vistas para las estructuras alternativas. Lo mejor es presentar un ejemplo.
Ejemplo: Se desea sumar los primeros 100 números naturales empezando por el 1:
Inicio
Dimensionar Numero, SUMA Como Entero
Numero <- 1//asignamos 1 al contador Numero
SUMA <- 0 //asignamos 0 a la variable SUMA
Repetir
SUMA <- SUMA + Numero
Numero <- Numero + 1 //incrementamos el contador
Hasta Que Numero <= 100//la condición en el REPETIR siempre se evalúa al final del ciclo
Escribir "La suma de los 100 primeros naturales es: ", SUMA
Fin
El contador (la variable N) es la variable de control del ciclo, y por lo tanto, al irse incrementando irá tomando valores que llevarán al final del ciclo y al fin del REPETIR. Si se diseña mal el algoritmo puede darse lugar a que se genere un ciclo infinito, es importante comprender que la variable contador debe incrementarse dentro del ciclo.
En Java para implementar la Estructura Repetir podemos utilizar la sentencia do y establecer la condición con whileal final:
public static void main(String[] args) {
int Numero, SUMA;
Numero = 1;
SUMA = 0;
do{
SUMA =SUMA + Numero;
Numero = Numero + 1;//podríamos usar N++ pero por cuestiones didácticas lo evitamos
}
while (Numero <= 100);
System.out.println("La suma de los 100 primeros números naturales es: " + SUMA);
}//fin main
2. Mientras
La estructura Mientras, a diferencia de la estructura Repetir, utiliza una variable centinela. Otra diferencia es que la condición se evalúa al principio, motivo por el cual puede darse el caso de que nunca se ingrese al ciclo y es por ello que también se la conoce como CICLO 0
Para escribir el algoritmo utilizaremos el mismo ejemplo, ya que por naturaleza se puede resolver tanto con un Repetir como con un Mientras, cuestión que no siempre es así.
Inicio
Dimensionar Numero, SUMA Como Entero
Numero <- 1//asignamos 1 al contador Numero
SUMA <- 0 //asignamos 0 a la variable SUMA
Mientras (Numero <= 100) hacer
SUMA <- SUMA + Numero
Numero <- Numero + 1 //incrementamos la variable centinela
Fin Mientras
Escribir "La suma de los 100 primeros naturales es: ", SUMA
Fin
En Java para implementar la Estructura Mientras podemos utilizar la sentencia while que evalúa la condición al principio del ciclo, es decir, antes de entrar a éste:
public static void main(String[] args) {
int Numero, SUMA;
Numero = 1;
SUMA = 0;
while(Numero <= 100){
SUMA = SUMA + Numero;
Numero = Numero + 1;//podríamos usar Numero++ pero por cuestiones didácticas lo evitamos
}
System.out.println("La suma de los 100 primeros números naturales es: " + SUMA);
}//fin main
3. Para
Esta estructura se suele usar cuando se conoce la cantidad de veces, o un rango dentro del cual, deben ejecutarse las acciones. Dentro de la estructura Para las acciones se ejecutarán un número EXACTO de veces. Esta estructura se conoce también como de Ciclo Exacto por este motivo.
Es importante tener en cuenta también que las acciones no deben modificar los valores de VC(variable de control), VI(valor inicial), VF(valor final) y el paso P(incremento variable de control), aunque algunos lenguajes de programación lo permiten.
La Sintaxis de esta estructura es la siguiente:
Para VC de VI a VF con paso P hacer
Acción 1
Acción 2
. . .
Acción n
Fin Para
Todas estas variables son numéricas y el paso puede ser tanto positivo como negativo.
El número exacto de veces que se ejecute la Estructura Para dependerá de una fórmula que podemos llamar QC (cantidad de ciclos) y que es igual a:
QC=(VF-VI+paso)/paso.
Por lo tanto:
- Si QC es igual a cero o negativo, no habrá ninguna vuelta, es decir, ningún ciclo;
- Si VF < VI con paso positivo no se ejecutará nunca;
- Si VF > VI y el paso es negativo, tampoco se ejecutará ningún ciclo.
En Java para implementar la Estructura Para utilizamos la sentencia for que evalúa la condición al principio del ciclo, es decir, antes de entrar a éste:
public static void main(String[] args) {
int Numero, SUMA;
SUMA = 0;
for(Numero=1; Numero<=100; Numero++){
SUMA = SUMA + Numero;
}
System.out.println("La suma de los 100 primeros números naturales es: " + SUMA);
}//fin main
Herencia en Java
Clases y Objetos
Como ya vimos en Java una clase está formada por atributos y métodos. Cuando se instancia una clase por se crea un objeto. Eso muestra el ejemplo anterior.
Los atributos son variables, pero una de las que podemos encontrar en Java, ya que en total podemos hablar de 4 tipos de variables:
- Variables de Instancia o atributos (variables no static): los valores son únicos para cada instancia de una clase, son los atributos sin la palabra reservada static.
- Variables de clase (son aquellas que usan la palabra reservada static): de esta forma hay sólo una y una sola copia de esa variable en memoria independientemente de cuántas instancias del objeto tengamos.
- Variables locales: son aquellas declaradas en un método o en un bloque de código. Básicamente sirven para guardar valores temporales puesto que existen mientras exista el método o el bloque de código.
- Parámetros: son variables que se pasan como argumentos. En el ejemplo las podemos ver en la lista de parámetros del constructor cuando se crea la Persona Pedro en la clase crearPersona.java.
La palabra reservada final: esta palabra aplicada a cualquier tipo de variable hace que la misma, una vez inicializada no se pueda modificar; es decir después de inicializada actúa como una constante. En algunos casos son útiles pero no siempre, depende de la situación.
La palabra reservada this: nos permite obtener el contexto. Pero ¿qué es el contexto? Puede decirse que el contexto es el ámbito de funcionamiento de un objeto.
Por ejemplo en la aplicación didáctica tenemos un contexto de la aplicación, que básicamente gestiona la conexión con la base de datos y la creación de los diferentes objetos o pantallas de la aplicación.
A su vez cada pantalla tiene su propio contexto, separado de las demás pantallas. Puede consultarse en los libros de la Unidad 2 y de la Unidad 3.
Los métodos son los que muestran el comportamiento de una clase o que permiten comunicar sus estados o inclusive comunicarse con otros objetos.
Un método se diferencia de otro en su signatura: la signatura de un método está formada por el nombre del método y los tipos de parámetros.
Nomenclatura de Atributos y Métodos
Es común que tanto los atributos como los métodos empiecen con cualquier carácter válido pero no hay que olvidar que son sensitivos a las mayúsculas y minúsculas, o como expresa el Tutorial :
Variable names are case-sensitive. A variable's name can be any legal identifier — an unlimited-length sequence of Unicode letters and digits, beginning with a letter, the dollar sign "$", or the underscore character "_". The convention, however, is to always begin your variable names with a letter, not "$" or "_". Additionally, the dollar sign character, by convention, is never used at all.
Lo subrayado es mío y está además copiado textualmente por los desastres que por ahí he visto. Además algo que no menciona el tutorial es que no hay que dejar espacios en blanco y siempre tener en cuenta que quien programa es un humano, no una máquina, así pues los nombres deben ser representativos.
Calificadores de Acceso
Los calificadores de acceso son 4 y se aplican tanto a las clases como a los atributos y métodos. El sentido de los calificadores de acceso es dar seguridad, es decir proteger a los datos, en definitiva los atributos.
Los calificadores de acceso determinan si otras clases pueden usar un atributo o variable de clase en particular o si pueden invocar un método en particular.
Existen dos niveles de control de acceso:
- A nivel de clase (o nivel superior): public , package
- A nivel de miembro (atributo o métodos dentro de una clase): public, private, protected y package
Nivel Superior
Una clase puede ser declarada con el modificador public, en cuyo caso la clase será visible para tods las clases de cualquier lugar (del mismo paquete o de cualquier otro paquete).
Si una clase no tiene ningún calificador (es el caso por defecto, también conocido como alcance de paquete o package), la clase será visible sólo dentro de su propio paquete. Un paquete es un grupo de clases relacionadas.
Declarar una clase con private no tiene sentido, no se podría usar directamente.
Nivel de los miembros de una clase
En este nivel también puden usarse los calificadores public y protected de la misma forma y con las mismas implicancias que en el caso del Nivel superior.
Pero en este caso tenemos dos calificadores de acceso adicionales: private y protected.
El calificador private implica que el miembro de la clase sólo puede ser accedido por su propia clase.
El calificador protected implica que el miembro sólo puede ser accedido dentro de su propio paquete y también en el caso particular de una subclase de esta clase que estuviera en otro paquete.
La siguiente tabla nos muestra el nivel de acceso a los miembros que permite cada calificador de acceso.
Niveles de Acceso
Modificador | Class | Package | Subclass | El mundo |
---|---|---|---|---|
public | Sí | Sí | Sí | Sí |
protected | Sí | Sí | Sí | No |
sin modificador | Sí | Sí | No | No |
private | Sí | No | No | No |
- La primera columna indica que la misma clase tiene acceso a los miembros definidos con cierto alcance; o dicho de otra forma, la clase tiene acceso a todos sus miembros independientemente del tipo de modificador aplicado. Como se puede apreciar una clase siempre tiene acceso a sus propios miembros.
- La segunda columna implica ponerse en un nivel superior al de la clase, si la clase en cuestión forma parte de un paquete con otras clases, estas clases tendrán acceso a los miembros de la clase excepto aquellos que hayan sido calificados con private.
- La tercera columna nos indica las relaciones de herencia que en Java se establecen entre una clase y sus clases hijas. En Java además una subclase sólo puede tener una clase padre o madre, se mire como se mire, es una sola clase de la que hereda todos sus miembros y atributos. En este caso las subclases tienen acceso a todos los miembros de la clase padre en la medida que el alcance sea public o protected. Este caso también es válido si existen subclases definidas en otro paquete.
- La cuarta columna indica que cualquier otra clase fuera del paquete, es decir de cualquier otro lado, tendrá acceso a un atributo definido como public, motivo por el cual no es conveniente utilizar este tipo de calificadores.
Los niveles de acceso nos afectan en dos formas: primero, cuando utilizamos clases que provienen de otra fuente como por ejemplo las clases definidas en la plataforma Java, que son externas a nuestra aplicación y por lo tanto el nivel de acceso determinará cuáles miembros de dichas clases podrán ser utilizados por nuestras propias clases. En segundo lugar, cuando escribamos nuestras clases tendremos que decidir qué nivel de acceso deberá tener cada atribudo y cada método.
¿Qué nivel de acceso elegir?
En esto lo mejor es elegir siempre que sea posible el nivel de acceso más restrictivo que tenga sentido para un miembro en particular: private.
Evitar atributos con el calificador public, excepto para el caso de constantes. Inclusive el uso de constantes públicas no es una buena idea para un código en producción.
Veremos unos ejemplos pero antes explicaremos el concepto de herencia.
Herencia y Polimorfismo
La herencia en Java es simple, es decir una clase sólo puede heredar de otra clase y no de muchas otras.
La clase hija hereda todos los miembros de la clase padre, es decir, tanto atributos como sus métodos, excepto el constructor o constructores que si bien son métodos particulares, no se heredan.
Uno de los grandes aciertos de la herencia es que agiliza el desarrollo de software y evita repetir código que ya está escrito; sin embargo ello no quiere decir que hay forzar la herencia así como así. En realidad en cursos avanzados de Java se ven otras relaciones además de la herencia, como la agregación y la composición.
Para que haya herencia en el código tiene que haber una relación que implique que la clase que hereda tiene elementos de la clase padre o madre que 'naturalmente' hereda.
Un típico ejemplo sería que tenemos la clase Vertebrado, la clase Equino que hereda de Vertebrado y la clase Caballo que hereda de Equino: O sea, puedo decir que un equino es un vertebrado, un caballo es un equino y por lo tanto también que un caballo es un vertebrado. La herencia en el ejemplo es natural, es decir, no está forzada. De hecho no debería forzarse.
Un código posible para este ejemplo podría ser:
class Vertebrado{
private int cantVertebras;
private String nombreEspecie;
public Vertebrado(int canti, String nom){
this.cantVertebras=canti;
this.nombreEspecie=nom;
}
public int getCantidadVertebras(){ return this.cantVertebras;}
public String getNombreEspecie(){ return this.nombreEspecie;}
public String digoSoyUn(){ return "soy un Vertebrado";}
}//fin clase Vertebrado
class Equino extends Vertebrado{
public Equino(int canti, String nom){
super(canti, nom);
}//fin constructor
@Override
public String digoSoyUn(){ return "soy un Equino";}
}//fin clase Equino
class Caballo extends Equino{
public Caballo(int canti, String nom){
super(canti, nom);
}//fin constructor
@Override
public String digoSoyUn(){ return "soy un Caballo";}
}//fin clase Caballo
El método runtime de la clase Herencia1.java crea los objetos:
public class Herencia1{
public static void main(String args[]){
Vertebrado ejemplo1 = new Vertebrado(60,"Vertebrado");
System.out.println("¿De qué especie es?\n" ejemplo1.digoSoyUn());
System.out.println("El valor de nombreEspecie =" ejemplo1.getNombreEspecie());
Equino ejemplo2 = new Equino(50,"Equino");
System.out.println("¿De qué especie es?\n" ejemplo2.digoSoyUn());
System.out.println("El valor de nombreEspecie =" ejemplo2.getNombreEspecie());
Caballo ejemplo3 = new Caballo(56,"Caballo");
System.out.println("¿De qué especie es?\n" ejemplo3.digoSoyUn());
System.out.println("El valor de nombreEspecie =" ejemplo3.getNombreEspecie());
}
}//fin clase Herencia1
Del ejemplo se puede concluir que:
- La herencia en Java se establece con la palabra reservada extends;
- Que la clase hija hereda todos los atributos y métodos de la clase madre/padre;
- Que no se hereda el constructor de la clase padre, por ello los datos se pasan al constructor con la palabra reservada super;
- Que si queremos cambiar un método de la clase padre en una clase hija (puesto que se heredará) debemos utilizar la sobreescritura de métodos (se indica con la palabra reservada @Overide);
¿Qué es polimorfismo?
Proviene de la biología e implica que una especie puede tener diferentes formas o estados. Aplicado a la POO quiere decir que una subclase puede tener un método con el mismo nombre que su clase padre y un diferente comportamiento. Esto lo hace la herencia, de modo tal que los métodos no interferirán entre sí. Es decir, es una consecuencia de la herencia: lo que hemos visto en el ejemplo anterior con el método digoSoyUn.
En la sección Ejercicios se presentan 3 videos que tratan el ejemplo anterior y dos derivaciones que demuestran un uso básico y simple de herencia y polimorfismo.