PROGRAMACION ORIENTADA A OBJETOS: HERENCIA

jueves, 11 de febrero de 2010

9.4- Relación entre superclases y subclases

En esta sección, se utiliza una jerarquía de herencia que contiene los tipos de los trabajadores en aplicación de nómina de una empresa para discutir la relación entre una superclase y la subclase. En esta empresa, los empleados por Comisión (que se representan como objetos de una superclase) se les paga un porcentaje de sus ventas, mientras que los empleados por Comisión con asalariados base (que se representan como objetos de una subclase) reciben un salario base más un porcentaje de sus ventas.

Dividimos nuestro análisis de la relación entre los empleados de la Comisión y la base de los empleados asalariados de la Comisión en cinco ejemplos. El primer ejemplo se declara CommissionEmployee clase, que hereda directamente de la clase Object y declara como variables de instancia privada de un nombre, apellido, número de seguro social, tipo de comisión y en cifras brutas (es decir, en total) cantidad de ventas.

El segundo ejemplo se declara la clase Circulo, que también hereda directamente de la clase Object y declara como variables de instancia privada de un nombre, apellido, número de seguro social, tipo de comisión, importe bruto de las ventas y el sueldo base. Creamos esta última clase de escribir cada línea de código de la clase requireswe pronto verá que es mucho más eficiente para crear esta clase que hereda de la clase EmpleadoPorComision.

El tercer ejemplo se declara una clase BasePlusCommissionEmployee2 separados que extiende la clase CommissionEmployee (es decir, un BasePlusCommissionEmployee2 es un CommissionEmployee que también tiene un sueldo base) y los intentos de acceso de clases privadas CommissionEmployee de membersthis resultados en los errores de compilación, ya que la subclase no puede acceder a las variables de instancia privada de la superclase .

El cuarto ejemplo muestra que si CommissionEmployee ejemplo de las variables son declaradas como protegidas, una clase BasePlusCommissionEmployee3 que se extiende CommissionEmployee2 clase pueden acceder a esos datos directamente. Para ello, declaramos CommissionEmployee2 clase con variables de instancia protegidos. Tanto de las clases Circulo contienen funcionalidad idéntica, pero se muestra cómo el BasePlusCommissionEmployee3 clase es más fácil crear y gestionar.

Después de discutir la conveniencia de utilizar las variables de instancia protegida, vamos a crear el quinto ejemplo, que establece las variables de instancia CommissionEmployee volver a CommissionEmployee3 privado en la clase para hacer cumplir buena ingeniería de software. A continuación se muestra cómo una clase BasePlusCommissionEmployee4 separado, que se extiende CommissionEmployee3 clase, puede utilizar métodos públicos CommissionEmployee3 para manipular las variables de instancia privada CommissionEmployee3's.


9.4.1. Crear y utilizar una clase EmpleadoPorComision

Empezamos por declarar la clase CommissionEmployee (Fig. 9.4). La Línea 4 se inicia la declaración de la clase, e indica que la clase EmpleadoPorComision se extiende (es decir, se hereda de) la clase de objeto (del paquete java.lang). Los programadores de Java utilizar la herencia para crear clases de las clases existentes. De hecho, todas las clases en Java (con excepción de objetos) se extiende una clase existente. Debido a que la clase CommissionEmployee extiende la clase de objeto, la clase CommissionEmployee hereda los métodos de la clase de objeto objectclass no tiene campos. De hecho, cada clase de Java, directa o indirectamente, hereda los métodos de objetos. Si una clase no se especifica que se extiende a otra clase, la nueva clase de objetos se extiende implícitamente. Por esta razón, los programadores no se cuenta "se extiende de objetos" en su codewe hacerlo en este ejemplo, para fines de demostración.

Figura 9.4. Clase CommissionEmployee representa un empleado pagado un porcentaje de las ventas brutas.


// Fig. 9.4: EmpleadoPorComision.java
// La clase EmpleadoPorComision representa a un empleado por comisión.

public class EmpleadoPorComision extends Object
{
private String primerNombre;
private String apellidoPaterno;
private String numeroSeguroSocial;
private double ventasBrutas; // ventas semanales totales
private double tarifaComision; // porcentaje de comisión

// constructor con cinco argumentos
public EmpleadoPorComision( String nombre, String apellido, String nss,
double ventas, double tarifa )
{
// la llamada implícita al constructor del objeto ocurre aquí
primerNombre = nombre;
apellidoPaterno = apellido;
numeroSeguroSocial = nss;
establecerVentasBrutas( ventas ); // valida y almacena las ventas brutas
establecerTarifaComision( tarifa ); // valida y almacena la tarifa de comisión
} // fin del constructor de EmpleadoPorComision con cinco argumentos

// establece el primer nombre
public void establecerPrimerNombre( String nombre )
{
primerNombre = nombre;
} // fin del método establecerPrimerNombre

// devuelve el primer nombre
public String obtenerPrimerNombre()
{
return primerNombre;
} // fin del método obtenerPrimerNombre

// establece el apellido paterno
public void establecerApellidoPaterno( String apellido )
{
apellidoPaterno = apellido;
} // fin del método establecerApellidoPaterno

// devuelve el apellido paterno
public String obtenerApellidoPaterno()
{
return apellidoPaterno;
} // fin del método obtenerApellidoPaterno

// establece el número de seguro social
public void establecerNumeroSeguroSocial( String nss )
{
numeroSeguroSocial = nss; // debe validar
} // fin del método establecerNumeroSeguroSocial

// devuelve el número de seguro social
public String obtenerNumeroSeguroSocial()
{
return numeroSeguroSocial;
} // fin del método obtenerNumeroSeguroSocial

// establece el monto de ventas totales del empleado por comisión
public void establecerVentasBrutas( double ventas )
{
ventasBrutas = ( ventas < 0.0 ) ? 0.0 : ventas;
} // fin del método establecerVentasBrutas

// devuelve el monto de ventas totales del empleado por comisión
public double obtenerVentasBrutas()
{
return ventasBrutas;
} // fin del método obtenerVentasBrutas

// establece la tarifa del empleado por comisión
public void establecerTarifaComision( double tarifa )
{
tarifaComision = ( tarifa > 0.0 && tarifa < 1.0 ) ? tarifa : 0.0;
} // fin del método establecerTarifaComision

// devuelve la tarifa del empleado por comisión
public double obtenerTarifaComision()
{
return tarifaComision;
} // fin del método obtenerTarifaComision

// calcula el salario del empleado por comisión
public double ingresos()
{
return tarifaComision * ventasBrutas;
} // fin del método ingresos

// devuelve representación String del objeto EmpleadoPorComision
public String toString()
{
return String.format( "%s: %s %s\n%s: %s\n%s: %.2f\n%s: %.2f",
"empleado por comision", primerNombre, apellidoPaterno,
"numero de seguro social", numeroSeguroSocial,
"ventas brutas", ventasBrutas,
"tarifa de comision", tarifaComision );
} // fin del método toString
} // fin de la clase EmpleadoPorComision


9,5 Figura pruebas de clase CommissionEmployee. 9 10 líneas de una instancia de un objeto Punto e invocar el constructor CommissionEmployee (líneas 1322 de la figura. 9,4) para iniciar con "Sue", como el nombre, "Jones", el apellido, "222-22-2222", como el número de seguridad social , 10000 como el importe bruto de las ventas y .06 como el tipo de comisión. Líneas de 1524 el uso CommissionEmployee de obtener métodos para recuperar el objeto de ejemplo, valores de las variables para la salida. Líneas de 2627 invocar los métodos del objeto setGrossSales y setCommissionRate para cambiar los valores de las variables de instancia y ventasTotales commissionRate. Líneas de 2930 la producción de la representación de cadena de la CommissionEmployee actualizado. Tenga en cuenta que cuando un objeto es de salida mediante el especificador de formato% s, el método toString del objeto que se invoca implícitamente a obtener una representación de cadena del objeto.


// Fig. 9.5: PruebaEmpleadoPorComision.java
// Prueba de la clase EmpleadoPorComision.

public class PruebaEmpleadoPorComision
{
public static void main( String args[] )
{
// crea instancia de objeto EmpleadoPorComision
EmpleadoPorComision empleado = new EmpleadoPorComision(
"Sue", "Jones", "222-22-2222", 10000, .06 );

// obtiene datos del empleado por comisión
System.out.println(
"Informacion del empleado obtenida por los metodos establecer: \n" );
System.out.printf( "%s %s\n", "El primer nombre es",
empleado.obtenerPrimerNombre() );
System.out.printf( "%s %s\n", "El apellido paterno es",
empleado.obtenerApellidoPaterno() );
System.out.printf( "%s %s\n", "El numero de seguro social es",
empleado.obtenerNumeroSeguroSocial() );
System.out.printf( "%s %.2f\n", "Las ventas brutas son",
empleado.obtenerVentasBrutas() );
System.out.printf( "%s %.2f\n", "La tarifa de comision es",
empleado.obtenerTarifaComision() );

empleado.establecerVentasBrutas( 500 ); // establece las ventas brutas
empleado.establecerTarifaComision( .1 ); // establece la tarifa de comisión

System.out.printf( "\n%s:\n\n%s\n",
"Informacion actualizada del empleado, obtenida mediante toString", empleado );
} // fin de main
} // fin de la clase PruebaEmpleadoPorComision






9.4.2. Creación de una clase sin Circulo utilizando la herencia
Ahora analizaremos la segunda parte de nuestra introducción a la herencia por la que se declara y prueba (totalmente nueva e independiente) de clase Circulo (fig. 9,6), que contiene un nombre, apellido, número de seguro social, importe bruto de las ventas, la tasa de comisión y sueldo básico. De los servicios públicos de clase Circulo de incluir un constructor Circulo (líneas 1525) y los métodos de los ingresos (100.103 líneas) y toString (106.114 líneas). Líneas de 2897 declarar pública métodos get y set para las variables de instancia privada de la clase (declarada en las líneas 712) Nombre, Apellido, socialSecurityNumber, ventasTotales, commissionRate y baseSalary. Estas variables y métodos de encapsular todos los aspectos necesarios de una base-empleado de la Comisión asalariados. Tenga en cuenta la similitud entre esta clase y clase CommissionEmployee (Fig. 9.4) en este ejemplo, aún no se aprovecharán de que la similitud.




Figura 9.6. Circulo de clase representa a un empleado que recibe un sueldo base, además de una comisión.

// Fig. 9.6: EmpleadoBaseMasComision.java
// La clase EmpleadoBaseMasComision representa a un empleado que recibe
// un salario base, además de la comisión.

public class EmpleadoBaseMasComision
{
private String primerNombre;
private String apellidoPaterno;
private String numeroSeguroSocial;
private double ventasBrutas; // ventas totales por semana
private double tarifaComision; // porcentaje de comisión
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 )
{
// implicit call to Object constructor occurs here
primerNombre = nombre;
apellidoPaterno = apellido;
numeroSeguroSocial = nss;
establecerVentasBrutas( ventas ); // valida y almacena las ventas brutas
establecerTarifaComision( tarifa ); // valida y almacena la tarifa de comisión
establecerSalarioBase( salario ); // valida y almacena el salario base
} // fin del constructor de EmpleadoBaseMasComision con seis argumentos

// establece el primer nombre
public void establecerPrimerNombre( String nombre )
{
primerNombre = nombre;
} // fin del método establecerPrimerNombre

// devuelve el primer nombre
public String obtenerPrimerNombre()
{
return primerNombre;
} // fin del método obtenerPrimerNombre

// establece el apellido paterno
public void establecerApellidoPaterno( String apellido )
{
apellidoPaterno = apellido;
} // fin del métodoestablecerApellidoPaterno

// devuelve el apellido paterno
public String obtenerApellidoPaterno()
{
return apellidoPaterno;
} // fin del método obtenerApellidoPaterno

// establece el número de seguro social
public void establecerNumeroSeguroSocial( String nss )
{
numeroSeguroSocial = nss; // debe validar
} // fin del método establecerNumeroSeguroSocial

// devuelve el número de seguro social
public String obtenerNumeroSeguroSocial()
{
return numeroSeguroSocial;
} // fin del método obtenerNumeroSeguroSocial

// establece el monto de ventas brutas
public void establecerVentasBrutas( double ventas )
{
ventasBrutas = ( ventas < 0.0 ) ? 0.0 : ventas;
} // fin del método establecerVentasBrutas

// devuelve el monto de ventas brutas
public double obtenerVentasBrutas()
{
return ventasBrutas;
} // fin del método obtenerVentasBrutas

// establece la tarifa de comisión
public void establecerTarifaComision( double tarifa )
{
tarifaComision = ( tarifa > 0.0 && tarifa < 1.0 ) ? tarifa : 0.0;
} // fin del método establecerTarifaComision

// devuelve la tarifa de comisión
public double obtenerTarifaComision()
{
return tarifaComision;
} // fin del método obtenerTarifaComision

// establece el salario base
public void establecerSalarioBase( double salario )
{
salarioBase = ( salario < 0.0 ) ? 0.0 : salario;
} // fin del método establecerSalarioBase

// devuelve el salario base
public double obtenerSalarioBase()
{
return salarioBase;
} // fin del método obtenerSalarioBase

// calcula los ingresos
public double ingresos()
{
return salarioBase + ( tarifaComision * ventasBrutas );
} //fin del método ingresos

// devuelve representación String de EmpleadoBaseMasComision
public String toString()
{
return String.format(
"%s: %s %s\n%s: %s\n%s: %.2f\n%s: %.2f\n%s: %.2f",
"empleado por comision con sueldo base", primerNombre, apellidoPaterno,
"numero de seguro social", numeroSeguroSocial,
"ventas brutas", ventasBrutas, "tarifa de comision", tarifaComision,
"salario base", salarioBase );
} // find el método toString
} // fin de la clase EmpleadoBaseMasComision



Figura 9.7 pruebas de la clase EmpleadoBaseMasComision. 9 a 11 líneas de una instancia de un objeto EmpleadoBaseMasComision y pasan los argumentos "Bob", "Lewis", "333-33-3333", 5000, .04 y 300 para el constructor como el nombre, apellido, número de seguridad social, las ventas brutas, la tasa de comisión y el salario base, respectivamente. Líneas de 1627 el uso Circulo de obtener métodos para recuperar los valores de las variables de instancia del objeto para la salida. La línea 29 llama al método establecerRadio el objeto de modificar el sueldo básico. EstablecerRadio Método (Fig. 9.6, las líneas de 8891) asegura que baseSalary variable de instancia no se le asigna un valor negativo, porque el sueldo básico de un empleado no puede ser negativo. Líneas de 3133 de la figura. 9,7 invocar método toString del objeto de forma explícita para conseguir la representación de cadena del objeto.

Figura 9.7. Programa de pruebas EmpleadoBaseMasComision.


// Fig. 9.7: PruebaEmpleadoBaseMasComision.java
// Prueba de la clases EmpleadoBaseMasComision.

public class PruebaEmpleadoBaseMasComision
{
public static void main( String args[] )
{
// crea instancia de objeto EmpleadoBaseMasComision
EmpleadoBaseMasComision empleado =
new EmpleadoBaseMasComision(
"Bob", "Lewis", "333-33-3333", 5000, .04, 300 );

// obtiene datos del empleado por comisión con sueldo base
System.out.println(
"Informacion del empleado obtenida por metodos establecer: \n" );
System.out.printf( "%s %s\n", "El primer nombre es",
empleado.obtenerPrimerNombre() );
System.out.printf( "%s %s\n", "El apellido es",
empleado.obtenerApellidoPaterno() );
System.out.printf( "%s %s\n", "El numero de seguro social es",
empleado.obtenerNumeroSeguroSocial() );
System.out.printf( "%s %.2f\n", "Las ventas brutas son",
empleado.obtenerVentasBrutas() );
System.out.printf( "%s %.2f\n", "La tarifa de comision es",
empleado.obtenerTarifaComision() );
System.out.printf( "%s %.2f\n", "El salario base es",
empleado.obtenerSalarioBase() );

empleado.establecerSalarioBase( 1000 ); // establece el salario base

System.out.printf( "\n%s:\n\n%s\n",
"Informacion actualizada del empleado, obtenida por toString",
empleado.toString() );
} // fin de main
} // fin de la clase PruebaEmpleadoBaseMasComision






9.4.3. Creación de una jerarquía de herencia CommissionEmployeeBasePlusCommissionEmployee


Ahora declaramos BasePlusCommissionEmployee2 clase (fig. 9,8), que extiende la clase CommissionEmployee (Fig. 9.4). Un objeto BasePlusCommissionEmployee2 es un CommissionEmployee (porque la herencia pasa de las capacidades de la clase CommissionEmployee), pero BasePlusCommissionEmployee2 clase también tiene ejemplo baseSalary variable (fig. 9.8, línea 6). Palabra clave se extiende en la línea 4 de la declaración de la clase indica la herencia. Como una subclase, BasePlusCommissionEmployee2 hereda las variables de instancia pública y la protección y los métodos de la clase EmpleadoPorComision. El constructor de la clase CommissionEmployee no es hereditaria. Así, los servicios públicos de BasePlusCommissionEmployee2 incluir su constructor (líneas 916), los métodos públicos heredados de la clase CommissionEmployee, establecerRadio método (líneas 1922), getBaseSalary método (líneas 2528), los ingresos de método (líneas 3135) y el método toString (líneas 3847).



// Fig. 9.8: EmpleadoBaseMasComision2.java
// EmpleadoBaseMasComision2 hereda de la clase EmpleadoPorComision.

public class EmpleadoBaseMasComision2 extends EmpleadoPorComision
{
private double salarioBase; // salario base por semana

// constructor con seis argumentos
public EmpleadoBaseMasComision2( String nombre, String apellido,
String nss, double ventas, double tarifa, double salario )
{
// llamada explícita al constructor de la superclase EmpleadoPorComision
super( nombre, apellido, nss, ventas, tarifa );

establecerSalarioBase( salario ); // valida y almacena el salario base
} // fin del constructor de EmpleadoBaseMasComision2 con seis argumentos

// establecer salario base
public void establecerSalarioBase( double salario )
{
salarioBase = ( salario < 0.0 ) ? 0.0 : salario;
} // fin del método establecerSalarioBase

// devuelve el salario base
public double obtenerSalarioBase()
{
return salarioBase;
} // fin del método obtenerSalarioBase

// calcula los ingresos
public double ingresos()
{
// no está permitido: tarifaComision y ventasBrutas son private en la superclase
return salarioBase + ( tarifaComision * ventasBrutas );
} // fin del método ingresos

// devuelve representación String de EmpleadoBaseMasComision2
public String toString()
{
// no está permitido: intentos por acceder a los miembros private de la superclase
return String.format(
"%s: %s %s\n%s: %s\n%s: %.2f\n%s: %.2f\n%s: %.2f",
"empleado por comision con sueldo base", primerNombre, apellidoPaterno,
"numero de seguro social", numeroSeguroSocial,
"ventas brutas", ventasBrutas, "tarifa de comision", tarifaComision,
"salario base", salarioBase );
} // fin del método toString
} // fin de la clase EmpleadoBaseMasComision2




9.4.4. CommissionEmployeeBasePlusCommissionEmployee Jerarquía de herencia Usando protegidas variables de instancia
Para habilitar el Circulo de clase para acceder directamente a variables de instancia primerNombre superclase, apellido, socialSecurityNumber, ventasTotales y commissionRate, podemos declarar como protegidas a los miembros de la superclase. Como vimos en la sección 9.3, los miembros de una superclase protegidas son heredados por todas las subclases de la superclase. Clase CommissionEmployee2 (Fig. 9.9) es una modificación de la clase CommissionEmployee (fig. 9,4) que declara variables de instancia Nombre, Apellido, socialSecurityNumber, ventasTotales y commissionRate protegidas (Figura 9.9, las líneas 610) y no privado. Otros que el cambio en el nombre de clase (y por tanto el cambio en el nombre del constructor) a CommissionEmployee2, el resto de la declaración de clase en la figura. 9.9 es idéntica a la de la figura. 9.4.


Figura 9.9. CommissionEmployee2 con variables de instancia protected



// Fig. 9.9: EmpleadoPorComision2.java
// La clase EmpleadoPorComision2 representa a un empleado por comisión.

public class EmpleadoPorComision2
{
protected String primerNombre;
protected String apellidoPaterno;
protected String numeroSeguroSocial;
protected double ventasBrutas; // ventas totales por semana
protected double tarifaComision; // porcentaje de comisión

// constructor con cinco argumentos
public EmpleadoPorComision2( String nombre, String apellido, String nss,
double ventas, double tarifa )
{
// la llamada implícita al constructor del objeto ocurre aquí
primerNombre = nombre;
apellidoPaterno = apellido;
numeroSeguroSocial = nss;
establecerVentasBrutas( ventas ); // valida y almacena las ventas brutas
establecerTarifaComision( tarifa ); // valida y almacena la tarifa de comisión
} // fin del constructor de EmpleadoPorComision2 con cinco argumentos

// establece el primer nombre
public void establecerPrimerNombre( String nombre )
{
primerNombre = nombre;
} // fin del método establecerPrimerNombre

// devuelve el primer nombre
public String obtenerPrimerNombre()
{
return primerNombre;
} // fin del método obtenerPrimerNombre

// establece el apellido paterno
public void establecerApellidoPaterno( String apellido )
{
apellidoPaterno = apellido;
} // fin del método establecerApellidoPaterno

// devuelve el apellido paterno
public String obtenerApellidoPaterno()
{
return apellidoPaterno;
} // fin del método obtenerApellidoPaterno

// establece el número de seguro social
public void establecerNumeroSeguroSocial( String nss )
{
numeroSeguroSocial = nss; // debe validar
} // fin del método establecerNumeroSeguroSocial

// devuelve el número de seguro social
public String obtenerNumeroSeguroSocial()
{
return numeroSeguroSocial;
} // fin del método obtenerNumeroSeguroSocial

// establece el monto de ventas brutas
public void establecerVentasBrutas( double ventas )
{
ventasBrutas = ( ventas < 0.0 ) ? 0.0 : ventas;
} // fin del método establecerVentasBrutas

// devuelve el monto de ventas brutas
public double obtenerVentasBrutas()
{
return ventasBrutas;
} // fin del método obtenerVentasBrutas

// establece la tarifa de comisión
public void establecerTarifaComision( double tarifa )
{
tarifaComision = ( tarifa > 0.0 && tarifa < 1.0 ) ? tarifa : 0.0;
} // fin del método establecerTarifaComision

// devuelve la tarifa de comisión
public double obtenerTarifaComision()
{
return tarifaComision;
} // fin del método obtenerTarifaComision

// calcula los ingresos
public double ingresos()
{
return tarifaComision * ventasBrutas;
} // fin del método ingresos

// devuelve representación String del objeto EmpleadoPorComision2
public String toString()
{
return String.format( "%s: %s %s\n%s: %s\n%s: %.2f\n%s: %.2f",
"empleado por comision", primerNombre, apellidoPaterno,
"numero de seguro social", numeroSeguroSocial,
"ventas brutas", ventasBrutas,
"tarifa de comision", tarifaComision );
} // fin del método toString
} // fin de la clase EmpleadoPorComision2




Clase BasePlusCommissionEmployee3 (Figura 9.10) es una modificación de BasePlusCommissionEmployee2 clase (fig. 9,8) que se extiende CommissionEmployee2 (línea 5) en lugar de la clase EmpleadoPorComision. Los objetos de BasePlusCommissionEmployee3 clase heredan las variables de instancia primerNombre CommissionEmployee2 está protegido, apellido, socialSecurityNumber, ventasTotales y commissionRateall estas variables están ahora protegidas miembros de BasePlusCommissionEmployee3. Como resultado, el compilador no genera errores al compilar la línea 32 de los ingresos de método y las líneas 4042 de método toString. Si otra clase se extiende BasePlusCommissionEmployee3, la nueva subclase hereda también los miembros protegidos.




// Fig. 9.10: EmpleadoBaseMasComision3.java
// EmpleadoBaseMasComision3 hereda de EmpleadoPorComision2 y tiene
// acceso a los miembros protected de EmpleadoPorComision2.

public class EmpleadoBaseMasComision3 extends EmpleadoPorComision2
{
private double salarioBase; // salario base por semana

// constructor con seis argumentos
public EmpleadoBaseMasComision3( String nombre, String apellido,
String nss, double ventas, double tarifa, double salario )
{
super( nombre, apellido, nss, ventas, tarifa );
establecerSalarioBase( salario ); // valida y almacena el salario base
} // fin del constructor de EmpleadoBaseMasComision3 con seis argumentos

// establece el salario base
public void establecerSalarioBase( double salario )
{
salarioBase = ( salario < 0.0 ) ? 0.0 : salario;
} // fin del método establecerSalarioBase

// devuelve el salario base
public double obtenerSalarioBase()
{
return salarioBase;
} // fin del método obtenerSalarioBase

// calcula los ingresos
public double ingresos()
{
return salarioBase + ( tarifaComision * ventasBrutas );
} // fin del método ingresos

// devuelve representación String de EmpleadoBaseMasComision3
public String toString()
{
return String.format(
"%s: %s %s\n%s: %s\n%s: %.2f\n%s: %.2f\n%s: %.2f",
"empleado por comision con salario base", primerNombre, apellidoPaterno,
"numero de seguro social", numeroSeguroSocial,
"ventas brutas", ventasBrutas, "tarifa comision", tarifaComision,
"salario base", salarioBase );
} // fin del método toString
} // fin de la clase EmpleadoBaseMasComision3




Figura 9.11 utiliza un objeto BasePlusCommissionEmployee3 para realizar las mismas tareas que la figura. 9,7 a cabo en un objeto Circulo (Fig. 9.6). Tenga en cuenta que los resultados de los dos programas son idénticos. A pesar de que declaró Circulo de clase sin necesidad de utilizar la herencia y declaró BasePlusCommissionEmployee3 clase mediante la herencia, ambas clases proporcionan la misma funcionalidad. El código fuente para BasePlusCommissionEmployee3 clase, que es de 45 líneas, es considerablemente más corto que el de la clase Circulo, que es de 115 líneas, porque BasePlusCommissionEmployee3 clase hereda la mayor parte de su funcionalidad desde CommissionEmployee2, mientras que la clase Circulo hereda la funcionalidad única clase de objetos. Además, ahora hay sólo una copia de la funcionalidad de empleado de la Comisión declaró en CommissionEmployee2 clase. Esto hace que el código sea más fácil de mantener, modificar y depurar, ya que el código relacionado con un empleado de la Comisión sólo existe en CommissionEmployee2 clase.



// Fig. 9.11: PruebaEmpleadoBaseMasComision3.java
// Prueba de la clase EmpleadoBaseMasComision3.

public class PruebaEmpleadoBaseMasComision3
{
public static void main( String args[] )
{
// crea instancia de un objeto EmpleadoBaseMasComision3
EmpleadoBaseMasComision3 empleadoBaseMasComision =
new EmpleadoBaseMasComision3(
"Bob", "Lewis", "333-33-3333", 5000, .04, 300 );

// obtiene datos del empleado por comision con sueldo base
System.out.println(
"Informacion del empleado, obtenida por los metodos establecer: \n" );
System.out.printf( "%s %s\n", "El primer nombre es",
empleadoBaseMasComision.obtenerPrimerNombre() );
System.out.printf( "%s %s\n", "El apellido es",
empleadoBaseMasComision.obtenerApellidoPaterno() );
System.out.printf( "%s %s\n", "El numero de seguro social es",
empleadoBaseMasComision.obtenerNumeroSeguroSocial() );
System.out.printf( "%s %.2f\n", "Las ventas brutas son",
empleadoBaseMasComision.obtenerVentasBrutas() );
System.out.printf( "%s %.2f\n", "La tarifa de comision es",
empleadoBaseMasComision.obtenerTarifaComision() );
System.out.printf( "%s %.2f\n", "El salario base es",
empleadoBaseMasComision.obtenerSalarioBase() );

empleadoBaseMasComision.establecerSalarioBase( 1000 ); // establece el salario base

System.out.printf( "\n%s:\n\n%s\n",
"Informacion actualizada del empleado, obtenida por toString",
empleadoBaseMasComision.toString() );
} // fin de main
} // fin de la clase PruebaEmpleadoBaseMasComision3







9.4.5. CommissionEmployeeBasePlusCommissionEmployee Jerarquía de herencia Usando las variables de instancia privada
Ahora volver a examinar nuestra jerarquía una vez más, esta vez utilizando las mejores prácticas de ingeniería de software. Clase CommissionEmployee3 (Figura 9.12) declara variables de instancia Nombre, Apellido, socialSecurityNumber, ventasTotales y commissionRate como privados (líneas 610) y proporciona setFirstName métodos públicos, getFirstName, setLastName, getLastName, setSocialSecurityNumber, getSocialSecurityNumber, setGrossSales, establecerY, setCommissionRate, getCommissionRate, las ganancias y toString para manipular estos valores. Tenga en cuenta que los métodos de los ingresos (8.588 líneas) y toString (líneas 9198) utiliza la clase de obtener métodos para obtener los valores de sus variables de instancia. Si decidimos cambiar el nombre de las variables ejemplo, los ingresos y declaraciones toString no requerirá modificationonly los cuerpos de los métodos get y set que manipular directamente las variables de instancia tendrá que cambiar. Tenga en cuenta que estos cambios se producen exclusivamente dentro de los cambios superclassno son necesarios para la subclase. La localización de los efectos de los cambios como éste es una buena práctica de ingeniería de software. Subclase BasePlusCommissionEmployee4 (Figura 9.13) hereda no CommissionEmployee3 de los métodos privados y pueden tener acceso a los miembros de la superclase privado a través de esos métodos.


// Fig. 9.12: EmpleadoPorComision3.java
// La clase EmpleadoPorComision3 representa a un empleado por comisión.

public class EmpleadoPorComision3
{
private String primerNombre;
private String apellidoPaterno;
private String numeroSeguroSocial;
private double ventasBrutas; // ventas totales por semana
private double tarifaComision; // porcentaje de comisión

// constructor con cinco argumentos
public EmpleadoPorComision3( String nombre, String apellido, String nss,
double ventas, double tarifa )
{
// la llamada implícita al constructor de Object ocurre aquí
primerNombre = nombre;
apellidoPaterno = apellido;
numeroSeguroSocial = nss;
establecerVentasBrutas( ventas ); // valida y almacena las ventas brutas
establecerTarifaComision( tarifa ); // valida y almacena la tarifa de comisión
} // fin del constructor de EmpleadoPorComision3 con cinco argumentos

// establece el primer nombre
public void establecerPrimerNombre( String nombre )
{
primerNombre = nombre;
} // fin del método establecerPrimerNombre

// devuelve el primer nombre
public String obtenerPrimerNombre()
{
return primerNombre;
} // fin del método obtenerPrimerNombre

// establece el apellido paterno
public void establecerApellidoPaterno( String apellido )
{
apellidoPaterno = apellido;
} // fin del método establecerApellidoPaterno

// devuelve el apellido paterno
public String obtenerApellidoPaterno()
{
return apellidoPaterno;
} // fin del método obtenerApellidoPaterno

// establece el número de seguro social
public void establecerNumeroSeguroSocial( String nss )
{
numeroSeguroSocial = nss; // debe validar
} // fin del método establecerNumeroSeguroSocial

// devuelve el número de seguro social
public String obtenerNumeroSeguroSocial()
{
return numeroSeguroSocial;
} // fin del método obtenerNumeroSeguroSocial

// establece el monto de ventas brutas
public void establecerVentasBrutas( double ventas )
{
ventasBrutas = ( ventas < 0.0 ) ? 0.0 : ventas;
} // fin del método establecerVentasBrutas

// devuelve el monto de ventas brutas
public double obtenerVentasBrutas()
{
return ventasBrutas;
} // fin del método obtenerVentasBrutas

// establece la tarifa de comisión
public void establecerTarifaComision( double tarifa )
{
tarifaComision = ( tarifa > 0.0 && tarifa < 1.0 ) ? tarifa : 0.0;
} // fin del método establecerTarifaComision

// devuelve la tarifa de comisión
public double obtenerTarifaComision()
{
return tarifaComision;
} // fin del método obtenerTarifaComision

// calcula los ingresos
public double ingresos()
{
return obtenerTarifaComision() * obtenerVentasBrutas();
} // fin del método ingresos

// devuelve representación String del objeto EmpleadoPorComision3
public String toString()
{
return String.format( "%s: %s %s\n%s: %s\n%s: %.2f\n%s: %.2f",
"empleado por comision", obtenerPrimerNombre(), obtenerApellidoPaterno(),
"numero de seguro social", obtenerNumeroSeguroSocial(),
"ventas brutas", obtenerVentasBrutas(),
"tarifa de comision", obtenerTarifaComision() );
} // fin del método toString
} // fin de la clase EmpleadoPorComision3




Figura 9.13. Clase BasePlusCommissionEmployee4 extiende CommissionEmployee3, que prevé únicamente las variables de instancia privada ..


// Fig. 9.13: EmpleadoBaseMasComision4.java
// La clase EmpleadoBaseMasComision4 hereda de EmpleadoPorComision3 y
// accede a los datos private de EmpleadoPorComision3's a través de los
// métodos public de EmpleadoPorComision3.

public class EmpleadoBaseMasComision4 extends EmpleadoPorComision3
{
private double salarioBase; // salario base por semana

// constructor con seis argumentos
public EmpleadoBaseMasComision4( String nombre, String apellido,
String nss, double ventas, double tarifa, double salario )
{
super( nombre, apellido, nss, ventas, tarifa );
establecerSalarioBase( salario ); // valida y almacena el salario base
} // fin del constructor de EmpleadoBaseMasComision4 con seis argumentos

// establece el salario base
public void establecerSalarioBase( double salario )
{
salarioBase = ( salario < 0.0 ) ? 0.0 : salario;
} // fin del método establecerSalarioBase

// devuelve el salario base
public double obtenerSalarioBase()
{
return salarioBase;
} // fin del método obtenerSalarioBase

// calcula los ingresos
public double ingresos()
{
return obtenerSalarioBase() + super.ingresos();
} // fin del método ingresos

// devuelve representación String de EmpleadoBaseMasComision4
public String toString()
{
return String.format( "%s %s\n%s: %.2f", "con sueldo base",
super.toString(), "sueldo base", obtenerSalarioBase() );
} // fin del método toString
} // fin de la clase EmpleadoBaseMasComision4





Figura 9.14 realiza las mismas manipulaciones de un objeto BasePlusCommissionEmployee4 como lo hizo la figura. 9.7 y la figura. 9,11 en los objetos de las clases Circulo y BasePlusCommissionEmployee3, respectivamente. Aunque cada uno de "base-empleado de la Comisión asalariados" clase se comporta igual, BasePlusCommissionEmployee4 clase es la mejor ingeniería. Mediante el uso de la herencia y llamando a los métodos que se ocultan los datos y asegurar la coherencia, hemos de manera eficiente y eficaz construido una clase bien diseñada.

Figura 9.14. Superclase variables de instancia privada son accesibles a través de una subclase de métodos públicos o protegidos heredados por la subclase.




// Fig. 9.14: PruebaEmpleadoBaseMasComision4.java
// Prueba de la clase EmpleadoBaseMasComision4.

public class PruebaEmpleadoBaseMasComision4
{
public static void main( String args[] )
{
// crea instancia de un objeto EmpleadoBaseMasComision4
EmpleadoBaseMasComision4 empleado =
new EmpleadoBaseMasComision4(
"Bob", "Lewis", "333-33-3333", 5000, .04, 300 );

// obtiene datos del empleado por comisión con sueldo base
System.out.println(
"Informacion del empleado obtenida por los metodos establecer: \n" );
System.out.printf( "%s %s\n", "El primer nombre es",
empleado.obtenerPrimerNombre() );
System.out.printf( "%s %s\n", "El apellido es",
empleado.obtenerApellidoPaterno() );
System.out.printf( "%s %s\n", "El numero de seguro social es",
empleado.obtenerNumeroSeguroSocial() );
System.out.printf( "%s %.2f\n", "Las ventas brutas son",
empleado.obtenerVentasBrutas() );
System.out.printf( "%s %.2f\n", "La tarifa de comision es",
empleado.obtenerTarifaComision() );
System.out.printf( "%s %.2f\n", "El salario base es",
empleado.obtenerSalarioBase() );

empleado.establecerSalarioBase( 1000 ); // establece el salario base

System.out.printf( "\n%s:\n\n%s\n",
"Informacion actualizada del empleado, obtenida por toString",
empleado.toString() );
} // fin de main
} // fin de la clase PruebaEmpleadoBaseMasComision4

No hay comentarios:

Publicar un comentario