Alcance de las variables
uso de "this"
Los parámetros de un
método en una
clase son conocidos como variables temporales. El valor y el nombre de
estas variables expiran cuando el método llamado regresa el control al
código que lo invocó. Cualquier variable definida en la lista de
parámetros del método o dentro del cuerpo del método permanecen en
memoria sólo lo que dura en ejecutarse el método llamado.
En java existen cuatro tipos de variables:
Variables
de Instancia
(Campos No-Estáticos). Los objetos almacenan su estado individual en
campos no-estáticos. Son declarados sin la palabra clave static. Sus
valores son únicos para cada instancia u objeto.
Variables de Clase
(Campos Estáticos). Son campos declarados con el modificador static
(esta palabra debera
estar definida para indicar este tipo de variables).
Hay sólo una copia de esta variable para todas la instancias de la
clase.
Variables Locales.
Es en donde los métodos de los objetos almacenan su estado temporal. Se
declaran parecido a los campos. No existe una palabra clave para
especificar que una variable es local sino que depende donde la
variable es declarada: dentro de los corchetes que definen un método.
Son accesibles sólo dentro del método que las declaró y no son
accesibles del resto de la clase.
Parámetros.
Son las variables que conforman la firma de un método. Son siempre
clasificados como variables y no como campos. También se encuentran en
otras construcciones que aceptan parámetros como los son los
constructores y manipuladores de excepciones.
El
scope ó alcance de las variable se refiere en que lugar del
programa una variable específica puede ser usada o referenciada. Por lo
general las variables pueden ser usada dentro del bloque de
instrucciones al que pertenecen y no fuera de estos. Un
bloque se
crea cada vez que tú abres y cierras corchetes ya sea para definir una
clase, método o cualquier otra construcción.
Más específicamente, el scope o alcance de una variable local abarca
desde donde se declaró, hasta el corchete de cierre del bloque al que
pertenecen El tiempo de vida de las variables depende del scope o
alcance donde fueron declaradas. Sólo se puede declarar una vez una
variable dentro de un bloque.
DEFINICION DE UNA CLASE
Una clase se define mediante la palabra Class y un nombre
class Deslizador{
// cuerpo de la clase
};
class DeslizadorDiapositivas extends Deslizador {
// cuerpo de la clase
}
la palabra extends
se
usa para indicar la superclase de una clase
LAS VARIABLES LOCALES
Las variables locales se definen dentro de métodos.
public static void main (String [] arguments ) {
int
total;
String
Tituloinforme;
boolean
activo;
//estan son varables
locales ya que
solo tienen ambito de acción entre los simbolos
{ }
}
esto se considera un metodo
LAS VARIABLES INSTANCIA
Se localizan en la definición de clase.
class PizarraHistoria extends PizarraHumanidades
{
String status;
int cantidad;
float puntuacion;
int numeroPrueba;
//
definicion de variables
instancia
}
VARIABLES DE CLASE
las variables de este tipo se aplican a la clase como un todo:
class PizarraHistoria extends PizarraHumanidades
{
String status;
int cantidad;
float puntuacion;
int numeroPrueba;
//
definicion de variables
instancia
static Int hora;
static final Int
maxPruebas=10; //definicion
de variables de
clase
}
METODOS
Se definen como comportamiento de los objetos
La definicion del métodos son cuatro partes:
Nombre
Parametros
Tipo devuelto
Cuerpo
La
experiencia ha demostrado que la mejor manera de desarrollar y mantener
un programa extenso es construirlo a partir de pequeñas piezas
sencillas, o módulos.
Los métodos
(también conocidos como funciones o procedimientos en otros lenguajes)
permiten al programador dividir un programa en módulos, por medio de la
separación de sus tareas en unidades autónomas. Usted ha declarado
métodos en todos los programas que ha escrito. Las instrucciones en los
cuerpos de los métodos se escriben sólo una vez, se ocultan de otros
métodos y se pueden reutilizar desde varias ubicaciones en un programa.
Como
sabe, un método se invoca mediante una llamada, y cuando el método que
se llamó completa su tarea, devuelve un resultado, o simplemente el
control al método que lo llamó. Una analogía a esta estructura de
programa es la forma jerárquica de la administración. Un jefe (el
solicitante) pide a un trabajador (el método llamado) que realice una
tarea y que le reporte (devuelva) los resultados después de completar
la tarea. El método jefe no sabe cómo el método trabajador realiza sus
tareas designadas.
Tal vez el
trabajador llame a otros métodos trabajadores, sin que lo sepa el jefe.
Este “ocultamiento” de los detalles de implementación fomenta la buena
ingeniería de software. La figura muestra al método jefe
comunicándose con varios métodos trabajadores en forma jerárquica. El
método jefe divide las responsabilidades entre los diversos métodos
trabajador. Aquí trabajador actúa como “método jefe” de trabajador 4 y
trabajador 5.
Para
cualquier clase importada en su programa, puede llamar a cualquier
método static especificando el nombre de la clase en la que está
declarado el método, seguido de un punto (.) y del nombre del método,
como sigue:
Nombre Clase.nonibreMétodo (argumentos)
System .out.println(Math.sqrt(900.0) );
En esta instrucción, el valor que devuelve sqrt se convierte
en el
argumento para el método println.
Los
argumentos para los métodos pueden ser constantes, variables o
expresiones. Si c = 13.0, d = 3 .0 y f = 4.0, entonces la instrucción
System .out.println(Math.sqrt(c + d * f ) );
calcula e imprime la raíz cuadrada de 13.0 + 3.0 * 4.0 = 2
5.0; a
saber, 5.0
Métodos de la clase Math
para mas informacion vea:
Para dar a conocer estos conceptos haremos un programa que
tenga el
metodo y la clase:



El programa completo es:
package listarrango;
class ListarRango{ //
inicio
de la clase
// declaramos el
metodo
int [ ] crearRango(int inferior, int
superior){ //
inicio del metodo
// el tipo de
retorno int [ ]
es un array
// el nombre del
metodo
crearRango
// parametros int
inferior, int
superior
// sigue el cuerpo
del metodo
int [ ]rango = new int[(superior - inferior)+1];
for (int i = 0; i < rango.length;
i++){ //inicio
del for
rango[i] = inferior++;
} //fin del for
return rango; //regresa
un
array el metodo
} // fin del
metodo
public static void main(String[] args) {
int[ ] rango;
ListarRango listar = new
ListarRango(); //
new
ListarRango() nombre de la clase
// objeto listar
rango =
listar.crearRango(5,15);
//pasamos
los parametros al metodo
System.out.println("El
array :");
for (int i = 0; i < rango.length; i++){
System.out.print(rango[i]+ " ");
}
}
} //fin de la
clase ListarRango
int [ ]
crearRango(int
inferior, int
superior)
int [ ] =
Tipo de retorno del
método
crearRango = Nombre del
método
(int
inferior, int
superior) = Parametros para recibir por el método
LA PALABRA CLAVE this
Hay ocasiones en las que resulta útil referirse al objeto desde el que se
está
ejecutando un método. En esas ocasiones se puede usar la
referencia especial de objeto this, pero cuidado, siempre dentro de un
método no estático.
Donde se usa:
En el cuerpo de definición de un método.
A que se refiere:
Al objeto que pertenece al método en el que se usa la palabra
clave
"this"
Para esto realizamos el ejemplo:

en la linea 8 hay una
advertencia, e
indica que hay una discrepancia entre la variables int test =
10;
corresponde a una variable instanciada de una clase (Palabrathis), y
int test = 20; corresponde a una variable local, JAVA evalua de la
parte interior hacia el exterior, y por lo que esta ultima variable
oculta a la primera:


package palabrathis;
public class Palabrathis {
int test = 10; //
es una
variable instanciada de la clase
void imprimirTest (){ //metodo
para imprimir la varaible local
int test = 20; // es una variable local
del metodo
System.out.println("El valor de la
variable local :
"+test);
}
void imprimirThis (){
//metodo
para imprimir la variable instanciada
System.out.println("El valor de la
variable
instanciada "+this.test); //this.test
solicita la variable this que es instanciada
//this solo actua
sobre las
variables instanciadas de clase
}
public static void main(String[] args) {
Palabrathis st = new Palabrathis(); //creacion del objeto st
st.imprimirTest(); //llamada
al metodo imprimirTest
Palabrathis st1 = new
Palabrathis(); //creacion
del
metodo st1
st1.imprimirThis(); //llamada
al metodo imprimirThis
}
}
AñADIR PARAMETROS A METODOS

Hasta ahora habíamos
visto como un
método o constructor puede recibir parámetros de los tipos de datos
primitivos en Java, como int, boolean, etc. e incluso de tipos
envoltorio como Integer. Vamos a ver que también se pueden recibir otro
tipo de parámetros.
Haremos un programa para demostrar como se pasan los
argumentos al
programa:
Hay que recordar como se pasan los argumentos al un programa:


Y el programa:


Puedes analizar y describir lo que hace el programa ?
package convertidor;
import java.lang.*;
public class Convertidor {
//
recibe los argumentos y reliza la
conversion
void aMayusculas(String[] texto){ // de minusculas a
mayusculas
con toUpperCase
for (int i =0;i<texto.length;
i++){ // el ciclo
revisa los argumentos
texto[i] =
texto[i].toUpperCase();
}
}
public static void main(String[]
argumentos) { //
en
lugar de args esta argumentos
// significa el nombre que le pasamos al array
//podemos poner el
nombre que
sea.
Convertidor convertidor =
new Convertidor();
convertidor.aMayusculas(argumentos);// aqui esta el nombre del
array
(argumentos)
for (int
i=0;i<argumentos.length; i++){
System.out.print(argumentos[i]+" ");
}
}
}
APLICACIONES JAVA
Las aplicaciones son clases de Java, que se pueden ejecutar a
ellas
mismas.
Una aplicación Java estara formada por una o varias clases.
Una aplicación necesita una clase de inicio que tenga un
método
main().
public
static void main
(String [ ] arguments) {
// proceso
}
Las partes de esto son:
public
.-- Significa
que esta disponible para otras clases y objetos.
static
.- significa
que el método main, es un método de clase.
void
.-- no devolvera
valor al termnimar el metodo, es decir los métodos usualmente devuelven
algún valor, para void no regresa valor alguno.
(String [
] arguments)
.-- Toma un parametro que es un array

METODOS CON EL MISMO NOMBRE PERO CON DIFERENTES ARGUMENTOS.
La firma de un método es
la
combinación del tipo de dato que regresa, su nombre y su lista de
argumentos. La sobrecarga de métodos es la creación de varios métodos
con el mismo nombre pero con diferentes firmas y definiciones. Java
utiliza el número y tipo de argumentos para seleccionar cuál definición
de método ejecutar. Java diferencia los métodos sobrecargados con base
en el número y tipo de argumentos que tiene el método y no por el tipo
que devuelve. Tambien existe la sobrecarga de constructores: Cuando en
una clase existen constructores múltiples, se dice que hay sobrecarga
de constructores.
Pueden declararse métodos
con el mismo
nombre en la misma clase, siempre y cuando tengan distintos conjuntos
de parámetros (que se determinan con base en el número, tipos y orden
de los parámetros).
A esto se le conoce como
sobrecarga de
métodos. Cuando se hace una llamada a un método sobrecargado, el
compilador de Java selecciona el método apropiado mediante un análisis
del número, tipos y orden de los argumentos en la llamada.
Por lo general, la sobrecarga de métodos se utiliza para crear varios
métodos con el mismo nombre que realicen la misma tarea o tareas
similares, pero con distintos tipos o números de argumentos.
Declaración de métodos sobrecargados
La clase
SobrecargaMetodos incluye dos
versiones sobrecargadas del método cuadrado:
una que calcula el cuadrado de un int (y devuelve un int) y otra que
calcula el cuadrado de un double (y devuelve un double). Aunque estos
métodos tienen el mismo nombre, además de listas de parámetros y
cuerpos similares, podemos considerarlos simplemente como métodos
diferentes. Puede ser útil si consideramos los nombres de los métodos
como “cuadrado de i nt” y “cuadrado de double", respectivamente.


el resultado:

durante el proceso de
escritura del
codigo sse presentaran mensajes de error pero es normal ya que se
llaman el metodos pero no esta, conforme se van creando los metodos los
errores se van retirando.
Aqui el programa completo:
package sobrecargametodos;
/**
*
@author Miguel
*/
//prueba los
metodos
sobrecargados
public class SobreCargaMetodos {
/**
* @param args the command line
arguments
*/
public static void main(String[] args) {
System.out.printf("El cuadrado del
entero 7 es %d\n", cuadrado(7));
System.out.printf("El cuadrado del
double 7.5 es %f\n", cuadrado(7.5));
} // fin de
main
//
método cuadrado con argumento int
public static int cuadrado(int valorInt)
{
System.out.printf("\n se
llama al metodo cuadrado con int %d\n ", valorInt);
return
valorInt*valorInt; //
regresa el valor
}
// fin del metodo
con int
// metodo
cuadrado con argumento double
public static double cuadrado(double
valorDouble)
{
System.out.printf("\n se
llama al metodos cuadrado con double %f\n", valorDouble);
return
valorDouble*valorDouble;
}// fin del
metodo double
}
Cómo se diferencian los métodos sobrecargados entre si
El compilador diferencia
los métodos
sobrecargados con base en su firma: una combinación del nombre del
método y del número, tipos y orden de sus parámetros. Si el compilador
sólo se basara en los nombres de los métodos durante la compilación, el
código anterior sería ambiguo; el compilador no "sabría" cómo
distinguir entre los dos métodos cuadrado. De manera interna, el
compilador utiliza nombres de métodos más largos que incluyen el nombre
del método original, el tipo de cada parámetro y el orden exacto de
ellos para determinar si los métodos en una clase son únicos en esa
clase.
METODOS CONSTRUCTOR Y SOBREESCRITURA DE METODOS
Como sabe, puede declarar su propio constructor para especificar cómo
deben inicializarse los objetos
de una clase. A continuación demostraremos una clase con varios
constructores sobrecargados, que
permiten a los objetos de esa clase inicializarse de distintas formas.
Para sobrecargar los constructores,
sólo hay que proporcionar varias declaraciones del constructor con
distintas firmas.
Los metodos constructor son llamandos de forma automatica
cuando se
crea un objeto.
Un método no puede ser llamado.
La palabra reservada para la creación de un objetos es NEW:
Localiza en la memoria
una posición
para el objeto creado.
Inicializa las
variables instancia
de un objeto.
Llama al método
constructor de la
clase.
Las ventajas de usar un método constructor:

El método constructor tendra el mismo nombre que la clase.
No tiene tipo de retorno.
No regresa valor por lo que no hay return.
Una clase puede tener mas de un costructor

la primer fase de estos es :
package circulo;
public class Circulo {
//primer
constructor con 3 parametros
int x,y,radio;
Circulo(int puntoX,int puntoY,int tamRadio ){ //aqui estan los 3
parametros
this.x = puntoX;
this.y = puntoY;
this.radio =
tamRadio;
}
Circulo (int puntoX,int puntoY){ //segundo constructor con
2
parametros
this(puntoX,puntoY,1); //relacionar los 2
cosntructor, esto
los relaciona con el otro constructor
}
void Resultado(){
int resultado = x*y*radio;
System.out.println(resultado);
}
public static void main(String[] args) {
Circulo circulo = new Circulo(); //aqui se presenta un
error porque
solicitamos el metodo constructor
// pero hay 2 metodos
por lo que es logico el error
(lo cambiamos por lo siguiente)
Circulo circulo = new Circulo(2,3,1); // aqui definimos el
metodos con el
de 2 parametros o 3 parametros
// con
ello estamos
indicando en
donde seran tomados
}
}
si lo compilamos se ejecuta sin errores pero no veremos
mingun
nresulatdo porque no hemos solicitado la funcion void para mostrar el
reultado para hacerlo veamos como modificamos, el programa, agregando
la llamada desde el constructor (de hecho el constructor esta
preparados para realizar esto).
al ejecutarlo el resultado sera:

esto se debe a que estamos solicitando el constructor con los 3
parametros y hemos colocado la llamada en el constructor en el que son
2 variables
package circulo;
public class Circulo {
//primer
constructor con 3 parametros
int x,y,radio;
Circulo(int puntoX,int puntoY,int tamRadio ){ //aqui estan los 3
parametros
this.x = puntoX;
this.y = puntoY;
this.radio = tamRadio;
Resultado();
}
Circulo (int puntoX,int puntoY){ //segundo constructor con
2
parametros
this(puntoX,puntoY,1); //relacionar los 2
cosntructor, esto
los relaciona con el otro constructor
Resultado();
}
void Resultado(){
int resultado = x*y*radio;
System.out.println(resultado);
}
public static void main(String[] args) {
//Circulo circulo = new Circulo(); //aqui se presenta un
error porque
solicitamos el metodo constructor
// pero hay 2 metodos por lo que es logico el error
Circulo circulo = new Circulo(2,5); // aqui definimos el
metodo con 2
parametros o 3 parametros
// con ello estamos indicando en donde seran tomados
}
}

Los métodos constructor se pueden sobrecargar.
Pueden declararse métodos
con el mismo
nombre en la misma clase, siempre y cuando tengan distintos conjuntos
de parámetros (que se determinan con base en el número, tipos y orden
de los parámetros).
A esto se le conoce como
sobrecarga de
métodos. Cuando se hace una llamada a un método sobrecargado,
el compilador de Java selecciona el método apropiado mediante un
análisis del número, tipos y orden
de los argumentos en la llamada. Por lo general, la sobrecarga de
métodos se utiliza para crear varios
métodos con el mismo nombre que realicen la misma tarea o tareas
similares, pero con distintos tipos o
números de argumentos.
SOBRESCRIBIR METODOS
Un método se define en una subclase con la misma firma que un método de
su Superclase
Realizaremos un programa
en 2 partes
para demostrar esto, usaremos la primera parte con una superclase y
usando unas variables las "imprimiremos" y veremos que una tercera
variable no se considera al mostrar el resultado, sobreescribimos el
método para incluirla, crearemos un nuevo proyecto llamado Impresion,
que vemos debajo.


Crear una clase llamada Imprimir:




Crear una clase llamada Subimprimir:

(decaramos e instanciamos la clase)
Primero modificaremos la classe Imprimir:

Modifiquemos la clase Subimprimir

y modifiquemos Impresion donde se encuentra la función main:

Realizemos un analisis de
esto, en
Impresion.java realiza una llamada a la clase Subimprimir que esta a su
vez tiene como super clase a Imprimir.java, que su proposito es
instanciar las variables x y, estableciendo método void imprimeme(),
que muestra los valores de X y Y, mostrando la clase y el nombre, sin
embargo en Subimprimir realiza herencia de Imprimir declarando z = 3, y
esta no se puede mostrar ya que esta como elemento de la misma clase no
de herencia, ejecutemos el programa:

pero si deseamos incluir
el valor de z
tendriams que modificar a Imprimir.java, pero no es necesrio solo
modifiquemos a Subimprimir.java para que pueda ser incluido:

este método se llama sobreescritura de metodos, sin modificar
las
clases previas o superclase se agregan mas elememntos para el
resultado, requerido.

Aqui los codigos:
IMPRESION.JAVA
-------------------------------------------------------------------
package impresion;
public class Impresion {
public static void main(String[] args) {
Subimprimir obj = new
Subimprimir();
obj.imprimeme();
}
}
IMPRIMIR.JAVA
--------------------------------------------------------------------
package impresion;
public class Imprimir {
int x = 0;
int y = 1;
void imprimeme()
{
System.out.println("X es :"+x+" y
el valor de y es "+y);
System.out.println("Soy una
instancia de clase "+this.getClass().getName());
}
}
SUBIMPRIMIR.JAVA
----------------------------------------------------------------------
package impresion;
public class Subimprimir extends Imprimir {
int z = 3;
void imprimeme(){
System.out.println("X es :"+x+" y el valor de y es
"+y+" z
tiene el valor de "+z);
System.out.println("Soy una instancia de clase
"+this.getClass().getName());
}
}
Las razones para sobrescribir el método son:
1.- Reemplazar la definicion del método original
completamente.
(que fue lo que se realizo anteriormente)
2.- Ampliar el método original con comportamientos orignales.
(para
ello se usa la palabra clave super)
super es un contenerdor y se hace referencia a la superclase
(se realizo un programa, con la función super en el
programa
herencia1 del capitulo anterior)
MODIFICADORES Y CONTROL DE ACCESO
MODIFICADORES .- Son palabras clave se añaden a las
definiciones,
cambiando su significado
Los modificadores de
acceso nos
introducen al concepto de encapsulamiento.
El encapsulamiento busca
de alguna
forma controlar el acceso a los datos que conforman un objeto o
instancia, de este modo podríamos decir que una clase y por ende sus
objetos que hacen uso de modificadores de acceso (especialmente
privados) son objetos encapsulados.
Los modificadores de
acceso permiten
dar un nivel de seguridad mayor a nuestras aplicaciones restringiendo
el acceso a diferentes atributos, métodos, constructores asegurándonos
que el usuario deba seguir una "ruta" especificada por nosotros para
acceder a la información.
Es muy posible que
nuestras
aplicaciones vayan a ser usadas por otros programadores o usuarios con
cierto nivel de experiencia; haciendo uso de los modificadores de
acceso podremos asegurarnos de que un valor no será modificado
incorrectamente por parte de otro programador o usuario. Generalmente
el acceso a los atributos se consigue por medio de los métodos get y
set, pues es estrictamente necesario que los atributos de una clase
sean privados.
Nota 1: Siempre se
recomienda
que los atributos de una clase sean privados y por tanto cada atributo
debe tener sus propios métodos get y set para obtener y establecer
respectivamente el valor del atributo.
Nota 2: Siempre
que se use una
clase de otro paquete, se debe importar usando import. Cuando dos
clases se encuentran en el mismo paquete no es necesario hacer el
import pero esto no significa que se pueda acceder a sus componentes
directamente.
La mayoría de las
declaraciones de
variables de instancia van precedidas por la palabra clave private. Al
igual que public, la palabra clave prívate es un modificador de acceso.
Las variables o los métodos declarados con
el modificador de acceso private son accesibles sólo para los métodos
de la clase en la que se declaran.
El proceso de declarar
variables de
instancia con el modificador de acceso private se
conoce como
ocultamiento de datos, u ocultamiento de información.
Las variables o métodos
declarados con
el modificador de acceso private sólo están accesibles para los métodos
de la clase en la que están declarados.
El modificador public
permite
que todas las clases puedas acceder a estos métodos o variables.
El modificador protect.
El uso del acceso
protected ofrece un
nivel intermedio de acceso entre public y private. Los miembros
protected
de una
superclase pueden ser utilizados por los miembros de
esa superclase, por los de sus subclases y por los de otras clases en
el mismo paquete; los miembros protected también tienen acceso a nivel
de paquete.
Todos los miembros public
y protected
de una superclase retienen su modificador de acceso original cuando se
convierten en miembros de la subclase (por ejemplo, los miembros public
de la superclase se convierten en miembros public de la subclase, y los
miembros protected de la superclase se vuelven en miembros protected de
la subclase). Los miembros private de una superclase no pueden
utilizarse fuera de la propia clase.
COMPARATIVA NIVELES DE
ACCESO
Visible
|
public
|
protected
|
default
|
private
|
Desde
la misma clase
|
Si
|
Si |
Si |
Si |
Desde
cualquier clase en el mismo paquete
|
Si |
Si |
Si |
No
|
Desde
cualquier clase fuera del paquete
|
Si
|
No
|
No |
No |
Desde
una subclase en el mismo paquete
|
Si
|
Si |
Si |
No
|
Desde
una subclase fuera del mismo paquete.
|
Si
|
Si
|
No
|
No
|

Los métodos private no pueden ser heredados
MODIFICADOR PRIVATE
Ninguna otra clase puede recuperar varibles de este tipo de
modificador
Veamos un ejemplo de esto:



package pruebacuenta;
import java.util.Scanner;
public class PruebaCuenta {
public static void main(String[] args) {
Cuenta cuenta1 = new Cuenta(50.00); // crea objeto Cuenta1
Cuenta cuenta2 = new Cuenta(-7.53); // crea objeto Cuenta2
//mostrar
el saldo unicial de la cuenta 1 cuenta 2
System.out.printf("saldo de cuenta 1:
$%.2f\n",
cuenta1.obtenerSaldo());
System.out.printf("saldo de cuenta 2:
$%.2f\n",
cuenta2.obtenerSaldo());
//crea
objeto Scanner para obtener la entrada de la ventana de comandos
Scanner entrada = new Scanner(System.in);
double montoDeposito;
System.out.print("El monto a depositar
cuenta 1 ");
montoDeposito = entrada.nextDouble();
System.out.printf("\nsumando %.2f al
saldo de cuenta
1\n\n",montoDeposito);
cuenta1.abonar(montoDeposito);//suma a
la cuenta 1
//mostrar
saldos
System.out.printf("Saldo de la cuenta 1
%.2f\n ",
cuenta1.obtenerSaldo());
System.out.printf("Saldo de la cuenta 2
%.2f\n ",
cuenta2.obtenerSaldo());
System.out.print("El monto a depositar
cuenta 2 ");
montoDeposito = entrada.nextDouble();
System.out.printf("\nsumando %.2f al
saldo de cuenta
1\n\n ",montoDeposito);
cuenta2.abonar(montoDeposito);//suma a
la cuenta 2
//mostrar
saldos
System.out.printf("Saldo de la cuenta 1
%.2f\n ",
cuenta1.obtenerSaldo());
System.out.printf("Saldo de la cuenta 2
%.2f\n ",
cuenta2.obtenerSaldo());
}
}

package pruebacuenta;
public class Cuenta {
private double saldo; // variable de instancia
que
almacena el saldo
//constructor
public Cuenta (double saldoInicial)
{
// valida
que saldo lnicial sea mayor que 0.0 ;
// si no lo es,
saldo se inicializa
con el valor predeterminado 0.0
if (saldoInicial > 0.0)
saldo = saldoInicial;
}//
termina
constructor
// abona
public void abonar (double monto)
{
saldo = saldo +
monto;
}
//
devuelve el saldo
public double obtenerSaldo ()
{
return saldo;
//
proporciona el valor de saldo al método que hizo la llamada
}
}
MODIFICADOR STATIC
Un método static es especial, ya que puede llamarse sin
tener que crear primero un objeto de la clase en la cual se declara ese
método.
Aunque la mayoría de los
métodos se
ejecutan en respuesta a las llamadas a métodos en objetos específicos,
éste no es siempre el caso. Algunas veces un método realiza una tarea
que no depende del contenido de ningún objeto. Dicho método se aplica a
la clase en la que está declarado como un todo, y se conoce como método
static o método de clase. Es común que las clases contengan métodos
static convenientes para realizar tareas comunes, coloque la palabra
clave static antes del tipo de valor de retorno en la declaración del
método.
Para cualquier clase
importada en su
programa, puede llamar a cualquier método static especificando el
nombre de la clase en la que está declarado el método, seguido de un
punto (.) y del nombre del método, como sigue:
Nombre Clase. nombreMétodo ( argumentos )
Ejemplo de modificador static



La declaración del método
maximo
comienza con la palabra clave public para indicar que el método está
“disponible para el público”: puede llamarse desde los métodos de otras
clases. La palabra clave static permite al método main (otro método
static) llamar a maximo, como se muestra, sin tener que calificar el
nombre del método con el nombre de la clase buscadorMaximo; los métodos
static en la misma clase pueden llamarse unos a otros de manera
directa. Cualquier otra clase que utilice a máximo debe calificar por
completo el nombre del método, con el nombre de la clase.
Considere la declaración
del método
maximo. La línea 24 indica que el método devuelve un valor double, que
el nombre del método es máximo y requiere tres parámetros double (x, y
y z) para realizar su tarea. Los parámetros múltiples se especifican
como una lista separada por comas. Cuando se hace la llamada a máximo
en la línea 24, los parámetros x, y y z se inicializan con los valores
de los argumentos numerol, numero2 y numero3, respectivamente.
Hay tres formas de llamar
a un método:
1. Utilizar el nombre de un método por sí solo para llamar a otro
método de la misma clase; como maximo (numerol, numero2, numero3).
2. Usar una variable que
contiene una
referencia a un objeto, seguida de un punto (.) y del nombre del método
para llamar a un método no static del objeto al que se hace referencia;
como la llamada al método.
3. Utilizar el nombre de
la clase y un
punto (.) para llamar a un método static de una clase, como Math. sqrt(
900.0 ).
Un método static sólo
puede llamar
directamente a otros métodos static de la misma clase (es decir,
mediante el nombre del método por sí solo) y sólo puede manipular de
manera directa variables static en la misma clase. Para acceder a los
miembros no static de la clase, un método static debe usar una
referencia a un objeto de esa clase. Recuerde que los métodos static
ese relacionan con una clase como un todo, mientras que los métodos no
static se asocian con una instancia específica (objeto) de la clase y
pueden manipular las variables de instancia de ese objeto.
Método Accesor
class ReverseString {
public static String reverseIt(String
source) {
int i, len = source.length();
StringBuffer dest = new
StringBuffer(len);
for (i = (len - 1); i >=
0; i--) {
dest.append(source.charAt(i));
}
return dest.toString();
}
}
Revisando este fragmento de codigo,
Las variables de ejemplar
de un objeto
están encapsuladas dentro del objeto, ocultas en su interior, seguras
frente a la inspección y manipulación por otros objetos.
Con ciertas excepciones bien definidas, los métodos del objeto no son
los únicos a través de los cuales un objeto puede inspeccionar o
alterar las variables de otro objeto.
La encapsulación de los datos de un objeto lo protege de la corrupción
de otros objetos y oculta los detalles de implementación a los objetos
extraños. Esta encapsulación de datos detrás de los métodos de un
objeto es una de las piedras angulares de la programación orientada a
objetos.
Los métodos utilizados para obtener información de un objeto son
conocidos como métodos accesores.
El método reverseIt()
utiliza dos
métodos accesores de String para obtener información sobre el string
source.
Primero utiliza el método accesor: length() para obtener la
longitud de la cadena source.
int len =
source.length();
Observa que a reverseIt()
no le
importa si el String mantiene su longitud como un entero, como un
número en coma flotante o incluso si calcula la longitud al vuelo.
reverseIt() simplemente utiliza el interface público del método
length() que devuelve la longitud del String como un entero. Es todo lo
que necesita saber reverseIt().
Segundo, utiliza el
método accesor:
charAt() que devuelve el carácter que está situado en la posición
indicada en su argumento.
source.charAt(i)
El carácter devuelto por charAt() es el que se añade al
StringBuffer dest. Como la variable del bucle i empieza al final de
source y avanza hasta el principio de la cadena, los caracteres se
añaden en orden inverso al StringBuffer.
MODIFICADOR PROTECTED
El uso del acceso
protected ofrece un
nivel intermedio de acceso entre public y private. Los miembros
protected de una superclase pueden ser utilizados por los miembros de
esa superclase, por los de sus subclases y por los de otras clases en
el mismo paquete; los miembros protected también tienen acceso a nivel
de paquete.
Todos los miembros public y protected de una superclase retienen su
modificador de acceso original cuando se convierten en miembros de la
subclase (por ejemplo, los miembros public de la superclase se
convierten en miembros public de la subclase, y los miembros protected
de la superclase se vuelven en miembros protected de la subclase). Los
miembros private de una superclase no pueden utilizarse fuera de la
propia clase. En cambio, están ocultos en sus subclases y se pueden
utilizar sólo a través de los métodos public o protected heredados de
la superclase.
Los métodos de una
subclase pueden
referirse a los miembros public y protected que se hereden de la
superclase con sólo utilizar los nombres de los miembros. Cuando un
método de la subclase sobrescribe al método heredado de la superclase,
éste último puede utilizarse desde la subclase si se antepone a su
nombre la palabra clave super y un punto (.) separador.
Declarar variables de
instancia
private ayuda a los programadores a probar, depurar y modificar
correctamente los sistemas. Si una subclase puede acceder a las
variables de instancia prívate de su superclase, las clases que hereden
de esa subclase podrían acceder a las variables de instancia también.
Esto propagaría el acceso a las que deberían ser variables de instancia
private , y se perderían los beneficios del ocultamiento de la
información.


package pruebaempleadoporcomision;
public class PruebaEmpleadoPorComision {
public static void main(String[] args) {
// crea instancia de
objeto
EmpleadoPorComision
EmpleadoPorComision empleado = new
EmpleadoPorComision("Sue","Jones","222-22-2222",10000,0.06);
// obtiene datos del empleado por comisión
System.out.println("Información del
empleado obtenida por los métodos establecer: \n ");
System.out.printf("%s %s\n","El primer
nombre es ",empleado.getPrimerNombre());
System.out.printf("%s %s\n","El apellido
paterno es :",empleado.getApellidoPaterno());
System.out.printf("%s %s\n","El numero
de Seguro Social",empleado.getNumeroSeguroSocial());
System.out.printf("%s %.2f\n","Las
ventas brutas son ",empleado.getVentasBrutas());
System.out.printf("%s %.2f","La tarifa
de comision es ",empleado.getTarifaComision());
empleado.setVentasBrutas(500);
empleado.setTarifaComision(.1);
System.out.printf("\n%s :
\n\n%s\n","Informacion actualizada del empleado obtenida mediante "
+ "toString ",empleado);
}//fin de
main
}//fin de la clase









Aqui el programa, la clase y la clase objet
PruebaEmpleadoPorComision
--------------------------------------------
package pruebaempleadoporcomision;
public class PruebaEmpleadoPorComision {
public static void main(String[] args) {
// crea instancia de
objeto
EmpleadoPorComision
EmpleadoPorComision empleado = new
EmpleadoPorComision("Sue","Jones","222-22-2222",10000,0.06);
// obtiene datos del empleado por comisión
System.out.println("Información del
empleado obtenida por los métodos establecer: \n ");
System.out.printf("%s %s\n","El primer
nombre es ",empleado.getPrimerNombre());
System.out.printf("%s %s\n","El apellido
paterno es :",empleado.getApellidoPaterno());
System.out.printf("%s %s\n","El numero
de Seguro Social",empleado.getNumeroSeguroSocial());
System.out.printf("%s %.2f\n","Las
ventas brutas son ",empleado.getVentasBrutas());
System.out.printf("%s %.2f","La tarifa
de comision es ",empleado.getTarifaComision());
empleado.setVentasBrutas(500);
empleado.setTarifaComision(.1);
System.out.printf("\n%s :
\n\n%s\n","Informacion actualizada del empleado obtenida mediante "
+ "toString ",empleado);
}//fin de
main
}//fin de la clase
EmpleadoPorComision
---------------------------------------
package pruebaempleadoporcomision;
public class EmpleadoPorComision extends Objet //realizar la clase Objet
(vacio)
{
private String PrimerNombre;
private String ApellidoPaterno;
private String NumeroSeguroSocial;
private double VentasBrutas;
private double TarifaComision;
//constructor con
5 argumentos
public EmpleadoPorComision(String Nombre,String Apellido, String
nss,double ventas,double tarifa)
{
// la
llamada implícita
al constructor de Object ocurre aqui
PrimerNombre = Nombre;
ApellidoPaterno = Apellido;
NumeroSeguroSocial = nss;
setVentasBrutas (ventas);//
valida y almacena las ventas brutas
setTarifaComision (tarifa);//
valida y almacena la tarifa de comisión
}// fin del
constructor de
EmpleadoPorComision con cinco argumentos
// establece el
primer nombre
public void setPrimerNombre (String Nombre)
{
PrimerNombre = Nombre;
}
// recupera el
nombre
public String getPrimerNombre()
{
return PrimerNombre;
}
// establece el
apellido
public void setApellidoPaterno (String Apellido)
{
ApellidoPaterno =Apellido;
}
//recupera el
apellido
public String getApellidoPaterno ()
{
return ApellidoPaterno;
}
// establece el
número de
seguro social
public void setNumeroSeguroSocial (String nss)
{
NumeroSeguroSocial = nss;
}
//regresa el valor
del numero
de seguro social
public String getNumeroSeguroSocial()
{
return NumeroSeguroSocial;
}
// establece del
monto de venta
public void setVentasBrutas (double ventas)
{
if (ventas >= 0.0)
VentasBrutas = ventas;
else
{
throw new
IllegalArgumentException
( "Las ventas brutas deben ser
mayores o igual
a 0.0" );
}
}
//regresa el valor
de ventas
public double getVentasBrutas()
{
return VentasBrutas;
}
//establecer la
tarifa de
comision
public void setTarifaComision (double tarifa)
{
if (tarifa >0.0
&& tarifa <1.0)
TarifaComision = tarifa;
else
{
throw new
IllegalArgumentException
(
"La tarifa de comision de be
ser mayor a 0.0 y menor a 0.0"
);
}
}
//devuelve la
tarifa comision
public double getTarifaComision()
{
return
TarifaComision;
}
// calcula ingresos
public double ingresos()
{
return
TarifaComision *
VentasBrutas;
}
// devuelve
representación String del objeto EmpleadoPorComision
@Override
//indica que este método sobrescribe el método de una superclase
public String toString()
{
return String.format("%s: %s %s\n%s:
%s\n%s:
%.2f\n%s: %.2f ",
"empleado
por comisión",PrimerNombre,ApellidoPaterno,
" numero
de seguro social ",NumeroSeguroSocial,
" ventas
brutas ",VentasBrutas,
" tarifa
de comisión",TarifaComision);
}
}
Objet
------------------------------
package pruebaempleadoporcomision;
/**
*
*
@author Miguel
*/
class Objet {
}
@Override
Si una clase base de Java
tiene un
nombre de método varias veces sobrecargado, redefinir dicho nombre en
la clase derivada no ocultará la implementación en ninguna de las
versiones de la clase base (a diferencia de lo que sucede en C++). Por
lo tanto, el mecanismo de sobrecarga funciona independientemente de si
el método ha sido definido en este nivel o en una clase base.
Lo más común es sobrecargar los métodos del mismo nombre, utilizando
exactamente la misma signatura y el mismo tipo de retorno. En caso
contrario, el código podría resultar confuso (lo cual es la razón por
la que C++ oculta todos los métodos de la clase base, para que no
cometamos lo que muy probablemente se trata de un error).
Java ha añadido al lenguaje la anotación @Override, que no es una
palabra clave pero puede usarse como si lo fuera. Cuando queremos
sustituir un método, esa es la razon que agregamos
public class EmpleadoPorComision extends Objet
donde Objet, será la extension de @Override podemos añadir esta
anotación y el compilador
generará un mensaje de error si sobrecargamos accidentalmente el método
en lugar de sustituirlo.
La anotación @Override evitará, así, que sobrecarguemos
accidentalmente un método cuando no es eso lo que queremos hacer.
MODIFICADOR FINAL
Cuando necesitamos que el valor de un atributo no cambie
durante el
transcurso de nuestro programa, debemos utilizar el modificador final
en su definición de la siguiente manera:
public final float pi = 3.14f;
En este ejemplo
utilizamos el
modificador final para almacenar el valor
de la constante matemática pi, ya que su valor nunca va a cambiar, si
por error intentásemos modificar el valor de un atributo definido como
final, el compilador nos notificaría un error.
Además, muchas veces los
modificadores
static y final se utilizan en
conjunto para definir constantes como puedes ver en el siguiente
ejemplo:
public class Constantes {
//Constantes publicas
public static final float PI =
3.141592f;
public static final float E =
2.728281f;
//MAIN
public static void
main(String[] args) {
System.out.println("PI = " + Constantes.PI);
System.out.println("E = " + Constantes.E);
}
}
Definiendo un atributo como public, static y final, obtenemos
una
constante que podrá ser accedida desde cualquier clase (public), el
acceso se podrá realizar sin tener que instanciar la clase mediante el
nombre de la clase (static) y su valor no podrá ser modificado en
ningún momento (final).
El modificador final también se puede utilizar sobre un
método o
una clase (tema de la herencia).
Para las clases también puede usarse final como:
public final
void getDatosUsuario()
{
// instrucciones
}
esto es para que la clase se vuelva mas rápida,
pero se
aconseja usarla cuando ya se hayan realizado las pruebas y
funcionalidad, requiriendo mas velocidad se aplica, y no afecta los
procesos, clases, subcalses, etc.
Ejercicio.-
pruebe establecer el
modificador final en los métodos el IDE de NetBeans le mostrara si la
instrucción esta en el lugar correcto.
POLIMORFISMO
Ahora explicaremos
y demostraremos el polimorfismo con las jerarquías de
herencia.
El polimorfismo nos
permite “programar
en forma general”, en vez de “programar en forma específica.”
En particular, nos
permite escribir
programas que procesen objetos que compartan la misma superclase (ya
sea de manera directa o indirecta)
como si todos fueran objetos de la superclase; esto puede simplificar
la programación.
Considere el siguiente ejemplo de polimorfismo. Suponga que crearemos
un programa que simula
el movimiento de varios tipos de animales para un estudio biológico.
Las clases Pez, Rana y Ave representan
los tipos de animales que se están investigando. Imagine que cada una
de estas clases extiende a
la superclase Animal, la cual contiene un método llamado mover y
mantiene la posición actual de un
animal, en forma de coordenadas x-y. Cada subclase implementa el método
mover. Nuestro programa
mantiene un arreglo tipo Animal, de referencias a objetos de las
diversas subclases de Animal.
Para simular
los movimientos de los animales, el programa envía a cada objeto el
mismo mensaje una vez por
segundo; mover. Cada tipo específico de Animal responde a un mensaje
mover de manera única; un
Pez podría nadar tres pies, una Rana, saltar cinco pies y un Ave, volar
diez pies.
Cada objeto sabe cómo
modificar sus coordenadas x-y en forma apropiada para su tipo
específico de movimiento.
Confiar en
que cada objeto sepa cómo “hacer lo correcto” (es decir, lo que sea
apropiado para ese tipo de objeto)
en respuesta a la llamada al mismo método es el concepto clave del
polimorfismo. El mismo mensaje (en
este caso, mover) que se envía a una variedad de objetos tiene “muchas
formas” de resultados; de aquí
que se utilice el término polimorfismo.
El
polimorfismo
promueve la extensibilidad: el software que invoca el comportamiento
polimórfico es independiente de los tipos de los objetos a los cuales
se envían los mensajes.
Es
posible incorporar en un sistema nuevos tipos de objetos que puedan
responder a las llamadas de los métodos existentes, sin necesidad de
modificar el sistema base. Sólo el código cliente que crea instancias
de los nuevos objetos debe modificarse para dar cabida a los nuevos
tipos.
El propósito de una clase
abstracta es
proporcionar una superclase apropiada, a partir de la cual puedan
heredar otras clases y, por ende, compartir un diseño común.
Para hacer una clase
abstracta, ésta
se declara con la palabra clave abstract. Por lo general, esta clase
contiene uno o más métodos abstractos, cada uno con la palabra clave
abstract en su declaración, como en:
public abstract void dibujar (); / / método abstracto
Los
métodos abstractos no proporcionan implementaciones. Una clase que
contiene uno o más métodos abstractos debe declararse de manera
explícita como abstract, aun si esa clase contiene métodos concretos
(no abstractos).
Situación a trabajar:
Una
compañía paga
semanalmente a sus empleados, quienes se dividen en cuatro
tipos:
Empleados
asalariados que reciben un salario semanal jijo, sin importar el número
de horas trabajadas;
Empleados
por horas, que perciben un sueldo por hora y pago por tiempo extra (es
decir, 1.5 veces la tarifa de su salario por horas), por todas las
horas trabajadas que excedan a 40 horas;
Empleados
por
comisión, que perciben un porcentaje de sus ventas
Empleados
asalariados por comisión, que obtienen un salario base más un
porcentaje de sus ventas.
Para
este periodo de pago, la compañía ha decidido recompensar a los
empleados asalariados por comisión, agregando un 10% a sus salarios
base. La compañía desea implementar una aplicación que realice sus
cálculos de nómina en firma polimórfico.
Estructura del programa
La
superclase abstracta Empleado declara la “interfaz” para la jerarquía;
esto es, el conjunto de métodos que puede invocar un programa en todos
los objetos Empleado. Aquí utilizamos el término “interfaz” en un
sentido general, para referirnos a las diversas formas en que los
programas pueden comunicarse con los objetos de cualquier subclase de
Empleado. Tener cuidado de no confundir la noción general de una
“interfaz” con la noción formal de una interfaz en Java.
Interfaz polimórfica para
las clases de
la jerarquía de Empleado.
// superclase abstracta Empleado
package empleado;
public abstract class Empleado {
private String PrimerNombre;
private String ApellidoPaterno;
private String NumeroSeguroSocial;
//constructor con 3 argumentos
public Empleado(String Nombre,String Apellido,
String Nss)
{
PrimerNombre = Nombre;
ApellidoPaterno = Apellido;
NumeroSeguroSocial = Nss;
} //fin del constructor
//establece
el primer nombre
public void setPrimerNombre(String Nombre)
{
PrimerNombre = Nombre;
}
//devuelve
el primer nombre
public String getPrimerNombre()
{
return PrimerNombre;
}
//
establece Apellido
public void setApellidoPaterno (String Apellido)
{
ApellidoPaterno = Apellido;
}
// devulve
el apellido
public String getApellidoPaterno()
{
return ApellidoPaterno;
}
// establece
el nss
public void setNumeroSeguroSocial(String Nss)
{
NumeroSeguroSocial = Nss;
}
// devulve
el numero de seguro social
public String getNumeroSeguroSocial()
{
return NumeroSeguroSocial;
}
// devuelve
representación String de un objeto Empleado
@Override
public String toString()
{
return String.format("%s %s\nnumero de seguro social:
%s",getPrimerNombre(),getApellidoPaterno(),getNumeroSeguroSocial());
}
// método
abstracto sobre escrito por la s subclases concretas
public abstract double Ingresos();
}
La subclase concreta EmpleadoAsalariado extiende a la clase Empleado y
sobrescribe el método
abstracto ingresos, lo cual convierte a EmpleadoAsalariado en una clase
concreta.


// La clase concreta Empleado
Asalariado extiende a laclase abstracta Empleado.
package empleado;
public class EmpleadoAsalariado extends
Empleado
{
private double SalarioSemanal;
//constructor de 4 argumentos
public EmpleadoAsalariado(String
Nombre,String Apellido, String Nss, double Salario)
{
super (Nombre,Apellido,Nss); //pasa
al constructor del Empleado
setSalarioSemanal (Salario); //valida
y almacena
}//
termina el constructor
//establece el salario
public void setSalarioSemanal(double
Salario)
{
if (Salario >= 0.0)
{SalarioSemanal =
Salario;}
else
{ throw new
IllegalArgumentException(" El salario Semannal debe ser mayor a 0.0 ");}
}//
fin del metodo setSalarioSemanal
// regresa salario
public double getSalarioSemanal()
{
return SalarioSemanal;
}
// calcula los
ingresos:sobrescribe el método abstracto ingresos en Empleado
@Override
public double Ingresos()
{
return
getSalarioSemanal();
}
// devuelve representación
String de un objeto EmpleadoAsalariado
@Override
public String toString()
{
return String.format(" empleado asalriado : %s\n%s:
$%,.2f",super.toString(),"salario semanal",getSalarioSemanal());
}
}
La subclase concreta EmpleadoPorHoras
La
clase EmpleadoPorHoras también extiende a Empleado (es uan subclase).
La clase incluye
un constructor que recibe como argumentos un primer nombre, un apellido
paterno, un
número de seguro social, un sueldo por horas y el número de horas
trabajadas. Se declaran los métodos set que asignan nuevos valores a
las variables de instancia sueldo y
horas. El método setSueldo asegura que sueldo sea no negativo,
y
el método setHoras asegura que horas esté entre 0 y 168 (el
número
total de horas en
una semana), ambos valores inclusive. La clase EmpleadoPorHoras también
incluye métodos get, para devolver los valores de sueldo y horas,
respectivamente; un método ingresos para calcular los ingresos
de
un EmpleadoPorHoras; y un método toString, que devuelve un objeto
String con el tipo del empleado (“ empleadoporhoras: ”), e información
específica para ese Empleado. El constructor de EmpleadoPorHoras, al
igual que el constructor
de EmpleadoAsalariado, pasa el primer nombre, el apellido paterno y el
número de seguro social al constructor de la superclase
Empleado para inicializar las variables de instancia private.
Además, el método
toString llama al
método toString de la superclase para obtener la información específica
del Empleado (es decir, primer nombre, apellido paterno y número de
seguro social); éste es otro excelente ejemplo de reutilización de
código.


// La clase EmpleadoPorHoras
extiende a Empleado.
package empleado;
public class EmpleadoPorHoras extends Empleado{
private double Sueldo; //sueldo por horas
private double Horas; //horas trabajadas por semana
//constructor
public EmpleadoPorHoras (String Nombre,String Apellido,String
Nss,double SueldoPorHoras,double HorasTrabajadas)
{
super(Nombre,Apellido,Nss);
setSueldo(SueldoPorHoras); // valida y almacena el sueldo por
horas
setHoras(HorasTrabajadas); // valida y almacena Horas trabajadas
}//fin del
constructor
// establece
sueldo
public void setSueldo (double SueldoPorHoras)
{
if (SueldoPorHoras >= 0.0)
Sueldo = SueldoPorHoras;
else
{
throw new IllegalArgumentException ("El sueldo debe ser mayor o igual a
0.0 ");
}
}//fin de
metodos setSueldo
//devuelve
el sueldo
public double getSueldo()
{
return Sueldo;
} //termina
metodos regresa sueldo
//establece
horas trabajadas
public void setHoras (double HorasTrabajadas)
{
if((HorasTrabajadas >=
0.0) && (HorasTrabajadas <=168))
Horas = HorasTrabajadas;
else
{
throw new IllegalArgumentException("Las horas trabajadas deben ser
mayor o igual a 0.0 o menor o igual que 168");
}
}//fin del
metodo HorasTrabajadas
//devulve
las horas trabajadas
public double getHoras()
{
return Horas;
}
// calcula los ingresos;
sobrescribe el método abstracto ingresos en Empleado
public double Ingresos ()
{
if (getHoras() <= 40) // no aplica
para tiempo extra
return
getSueldo() * getHoras();
else
{
return
40*getSueldo()+(getHoras() -40)*getSueldo()*1.5;
}
} //fin metodo ingresos
// devuelve
representación String de un objeto EmpleadoPorHoras
@Override
public String toString()
{
return String.format("empleado por horas: %s\n%s: $%,.2f; %s:
%,.2f",super.toString(),"sueldo por hora",getSueldo(),"Horas
Trabajadas",getHoras());
}//fin del metodo string
}
La clase
EmpleadoPorComision extiende a la clase Empleado. Esta clase
incluye a
un constructor que recibe como argumentos un primer nombre, un
apellido, un número
de seguro social, un monto de ventas y una tarifa de comisión; los
métodos set,
para asignar nuevos valores a las variables de instancia TarifaComision
y VentasBrutas,
respectivamente; métodos get,
que obtienen los valores de estas variables
de instancia; el método Ingresos para calcular los ingresos de un
EmpleadoPorComision; y el método toString que devuelve el tipo
del
empleado; “empleado por
comisión: ”, e información específica del empleado. El constructor
también pasa el primer nombre, el
apellido y el número de seguro social al constructor de Empleado para
inicializar las variables
de instancia private de Empleado. El método toString llama al método
toString de la superclase para obtener la información
específica
del Empleado (es decir, primer nombre, apellido paterno
y número de seguro social).

package empleado;
public class EmpleadoPorComision extends Empleado{
private double VentasBrutas;//ventas totales por totales
private double TarifaComision;//porcentaje de comision
//constructor con
5 argumentos
public EmpleadoPorComision(String Nombre,String
Apellido,String Nss,double Ventas,double Tarifa)
{
super(Nombre,Apellido,Nss);
setVentasBrutas(Ventas);
setTarifaComision(Tarifa);
}//final del
constructor
//establecer
tarifa de comision
public void setTarifaComision(double Tarifa)
{
if (Tarifa > 0.0 &&
Tarifa < 1.0)
TarifaComision = Tarifa;
else
throw new IllegalArgumentException ("la tarifa comsion debe ser mayor a
0.0 o menor a 0.0" );
}
// devulve la
tarifa comision
public double getTarifaComision()
{
return TarifaComision;
}
public void setVentasBrutas(double Ventas)
{
if (Ventas>= 0.0)
VentasBrutas = Ventas;
else
throw new IllegalArgumentException ("Las ventas brutas deben ser
mayores o iguales a 0.0");
}
public double getVentasBrutas()
{
return VentasBrutas;
}
//calcula los
ingresos; sobrescribe el método abstracto ingresos en Empleado
@Override
public double Ingresos()
{
return getTarifaComision() *
getVentasBrutas();
}// fin del metodo
ingresos
// devuelve
representación String de un objeto EmpleadoPorComision
@Override
public String toString()
{
return String.format("%s: %s\n%s: $%,.2f; %s: %.2f","empleado por
comisión",super.toString (),"ventas brutas" ,getVentasBrutas(),"tarifa
de comisión" ,getTarifaComision() );
}
}
La clase
EmpleadoBaseMasComision extiende a la clase
EmpleadoPorComision y,
por lo tanto, es una subclase indirecta de la clase Empleado. La clase
EmpleadoBaseMasComision tiene
un constructor que recibe como argumentos un primer nombre, un
apellido paterno,
un número de seguro social, un monto de ventas, una tarifa de comisión
y un salario base. Después
pasa todos estos parámetros, excepto el salario base, al constructor de
EmpleadoPorComision para inicializar los miembros heredados.
EmpleadoBaseMasComision también contiene un método
establecer (set) para asignar un nuevo valor a la variable de instancia
salarioBase y un método
obtener (get) para devolver el valor de salarioBase . El método
ingresos calcula los ingresos de un EmpleadoBaseMasComision.
Observe que el método ingresos
llama al método ingresos de la superclase EmpleadoPorComision para
calcular la porción con base
en la comisión de los ingresos del empleado; éste es otro buen ejemplo
de reutilización de código. El
método toString de EmpleadoBaseMasComision crea una representación
String de
un EmpleadoBaseMasComision , la cual contiene “ con salario base",
seguida del objeto String que
se obtiene al invocar el método toString de la superclase
EmpleadoPorComision (otro buen ejemplo
de reutilización de código), y después el salario base. El resultado es
un objeto String que empieza con
“con SalarioBaseEmpleadoPorComisión”, seguido del resto dé la
información de EmpleadoBaseMasComision. Recuerde que el método toString
de EmpleadoPorComision obtiene el primer nombre,
el apellido paterno y el número de seguro social del empleado mediante
la invocación al método
toString de su superclase (es decir, Empleado); otro ejemplo más de
reutilización de código. El método
toString de EmpleadoBaseMasComision inicia una cadena de llamadas a
métodos que abarcan los
tres niveles de la jerarquía de Empleado.


package empleado;
public class EmpleadoBaseMasComision extends EmpleadoPorComision
{
private double SalarioBase;//salario base por semana
//constructor
con seis argumentos
public EmpleadoBaseMasComision(String Nombre,String Apellido,String
Nss,double Ventas,double Tarifa,double Salario)
{
super(Nombre,Apellido,Nss,Ventas,Tarifa);
setSalarioBase(Salario);
}//fin del
costructor
//establecer
salario base
public void setSalarioBase(double Salario)
{
if (Salario >= 0.0)
SalarioBase = Salario;
else
throw new IllegalArgumentException("El salario base debe der mayor o
igual que 0.0 ");
}
// devuelva
salario minimo
public double getSalarioBase()
{
return SalarioBase;
}
// calcula
los ingresos; sobrescribe el método ingresos en EmpleadoPorComision
@Override
public double Ingresos()
{
return getSalarioBase() +
super.Ingresos();
}//fin del
metodo
// devuelve
representación String de un objeto EmpleadoBaseMasComision
@Override
public String toString()
{
return String.format("%s %s; %s: $%,.2f","con salario
base",super.toString(),"salario
base",getSalarioBase());
}
}
El procesamiento polimórfico, el operador instanceof y la
conversión descendente
Para probar nuestra jerarquía de
Empleado, la aplicación a continuación crea un objeto de cada una de
las cuatro clases concretas EmpleadoAsalariado, EmpleadoPorHoras,
EmpleadoPorComision y EmpleadoBaseMasComision. El programa manipula
estos objetos, primero mediante variables del mismo tipo de cada objeto
y después mediante el polimorfismo, utilizando un arreglo de variables
Empleado.
Al procesar los
objetos mediante el polimorfismo, el programa incrementa el salario
base de cada EmpleadoBaseMasComision en un 10% ; para esto se requiere
determinar el tipo del objeto en tiempo de ejecución. Por último, el
programa determina e imprime en forma polimórfica el tipo de cada
objeto en el arreglo Empleado.Se crean objetos de cada una de las
cuatro subclases concretas de Empleado. Se imprimen en pantalla la
representación String y los ingresos de cada uno de estos objetos sin
usar el polimorfismo. El método prrintf llama en forma implícita
al método toString de cada objeto, cuando éste se imprime en pantalla
como un objeto String con el especificador de formato %s.

package empleado;
public class PruebaSistemaNomina
{
public static void main (String[] args)
{
EmpleadoAsalariado empleadoAsalariado = new
EmpleadoAsalariado("Juan","Sanchez","111-11-1111",800.00);
EmpleadoPorHoras empleadoPorHoras = new
EmpleadoPorHoras("Karina","Garcia","222-22-2222",16.75,40);
EmpleadoPorComision empleadPorComision = new
EmpleadoPorComision("Susana","Martinez","333-33-3333",10000,0.06);
EmpleadoBaseMasComision empleadoBaseMasComision = new
EmpleadoBaseMasComision("Roberto","Gasca","444-44-4444",5000,0.04,300);
System.out.println(" Empleados procesados por
separado:\n");
System.out.printf("%s\n%s: $%,.2f\n \n ",empleadoAsalariado,
"ingresos",empleadoAsalariado.Ingresos());
System.out.printf("%s\n%s: $%,.2f\n \n ",empleadoPorHoras,
"ingresos", empleadoPorHoras.Ingresos());
System.out.printf("%s\n%s: $%,.2f\n \n ",empleadPorComision,
"ingresos",empleadPorComision.Ingresos());
System.out.printf("%s\n%s: $%,.2f\n \n
",empleadoBaseMasComision,"ingresos",empleadoBaseMasComision.Ingresos());
// crea un arreglo
Empleado de cuatro elementos
Empleado[] empleados = new Empleado[4];
// inicializa el
arreglo con objetos Empleado
empleados[0] = empleadoAsalariado;
empleados[1] = empleadoPorHoras;
empleados[2] = empleadPorComision;
empleados[3] = empleadoBaseMasComision;
System.out.println("Empleados procesados en forma polimorfica
:\n");
// procesa en forma
genérica a cada elemento en el arreglo de empleados
for (Empleado EmpleadoActual : empleados )
{
System.out.println(EmpleadoActual); // invoca a toString
//
determina si el elemento es un EmpleadoBaseMasComision
if(EmpleadoActual instanceof EmpleadoBaseMasComision)
{
// conversión descendente de la
referencia de Empleado
// a una referencia de EmpleadoBaseMasComision
EmpleadoBaseMasComision empleado =
(EmpleadoBaseMasComision) EmpleadoActual;
empleado.setSalarioBase(1.10*empleado.getSalarioBase());
System.out.printf(" el nuevo salario base con 10%% de aumento es :
$%,.2f\n",empleado.getSalarioBase());
}
}
}
}
http://www.sc.ehu.es/sbweb/fisica/cursoJava/fundamentos/clases1/string.htm
Ditel 9na. edicion pag. 258, Sobrecarga de metodos
Ditel 9na. edicion pag. 242, Metodo static
Ditel 9na. edicion pag. 348, 403 Sobrecarga de constructores
http://www.sc.ehu.es/sbweb/fisica/cursoJava/fundamentos/colecciones/stringtokenizer.htm
http://www.w3ii.com/es/java_util/default.html
http://www.w3ii.com/default.html
https://users.dcc.uchile.cl/~lmateu/Java/Apuntes/tiposprim.htm
http://labojava.blogspot.mx/2012/05/casteos.html
http://www.sc.ehu.es/sbweb/fisica/cursoJava/fundamentos/estatico/math/math.htm
http://www.sc.ehu.es/sbweb/fisica/cursoJava/Intro.htm
https://www.solvetic.com/tutoriales/article/974-java-palabra-reservada-super/
http://www.binarykode.com/bdescargas/Manuales%20y%20Documentos/JAVA/Interfaces%20de%20Usuario/Tutorial%20JAVA%20avanzado%20(I)/string/accessors.html
https://www.aprenderaprogramar.com/index.php?option=com_content&view=article&id=653:ejemplo-de-herencia-en-java-uso-de-palabras-clave-extends-y-super-constructores-con-herencia-cu00686b&catid=68&Itemid=188