gentoo linux, java, software libre y otras hierbas
dic, 05 2007 - 5:54 pm

[código] Programación Orientada a Objetos: Polimorfismo (1)

En esta sección puedes descargar ejemplos de Polimorfismo (Programación Orientada a Objetos). Los ejemplos muestran la diferencia de clases abstractas (abstract) y clases concretas; además de presentar las interfaces, que es el “reemplazo” de la llamada “herencia múltiple” de C++. También presenta el concepto de las clases anidadas, las cuales utilizamos en este caso para el manejo de eventos de componentes de la GUI. Véase especialmente tres ejemplos prácticos de polimorfismo: un sistema de nóminas, una jerarquía de figuras encabezada por una clase abstract y una jerarquía de clases encabezada por una interfaz.

Asignación de referencias de superclase y subclase a la variable de tipo superclase y subclase

Este ejemplo contiene 3 clases; la primera de ellas es la clase Punto3:

// La declaración de la clase Punto representa un par de coordenadas x-y.

public class Punto3 {
   private int x;  // parte x de un par de coordenadas
   private int y;  // parte y de un par de coordenadas

   // constructor sin argumentos
   public Punto3()
   {
      // la llamada implícita al constructor de Object ocurre aquí
   } 

   // constructor
   public Punto3( int valorX, int valorY )
   {
      // la llamada implícita al constructor de Object ocurre aquí
      x = valorX;  // no hay necesidad de validación
      y = valorY;  // no hay necesidad de validación
   } 

   // establecer x en el par de coordenadas
   public void establecerX( int valorX )
   {
      x = valorX;  // no hay necesidad de validación
   } 

   // devolver x del par de coordenadas
   public int obtenerX()
   {
      return x;
   } 

   // establecer y en el par de coordenadas
   public void establecerY( int valorY )
   {
      y = valorY;  // no hay necesidad de validación
   } 

   // devolver y del par de coordenadas
   public int obtenerY()
   {
      return y;
   } 

   // devolver la representación String del objeto Punto3
   public String toString()
   {
      return "[" + obtenerX() + ", " + obtenerY() + "]";
   } 

} // fin de la clase Punto3

La segunda es la clase Circulo4:

// La clase Circulo4 hereda de Punto3 y accede a las variables x e y
// de Punto 3 mediante los métodos public de Punto3.

public class Circulo4 extends Punto3 {

   private double radio;  // El radio de Circulo4

   // constructor sin argumentos
   public Circulo4()
   {
      // la llamada implícita al constructor de Punto3 ocurre aquí
   } 

   // constructor
   public Circulo4( int valorX, int valorY, double valorRadio )
   {
      super( valorX, valorY );  // llama al constructor de Punto3 explícitamente
      establecerRadio( valorRadio );
   } 

   // establecer el radio
   public void establecerRadio( double valorRadio )
   {
      radio = ( valorRadio < 0.0 ? 0.0 : valorRadio );
   } 

   // devolver el radio
   public double obtenerRadio()
   {
      return radio;
   } 

   // calcular y devolver el diámetro
   public double obtenerDiametro()
   {
      return 2 * obtenerRadio();
   } 

   // calcular y devolver la circunferencia
   public double obtenerCircunferencia()
   {
      return Math.PI * obtenerDiametro();
   } 

   // calcular y devolver el área
   public double obtenerArea()
   {
      return Math.PI * obtenerRadio() * obtenerRadio();
   } 

   // devolver la representación String del objeto Circulo4
   public String toString()
   {
      return "Centro = " + super.toString() + "; Radio = " + obtenerRadio();
   } 

} // fin de la clase Circulo4

Y la tercera es la clase PruebaRelacionJerarquia1:

// Asignación de referencias de superclases y subclases a variables tipo
// superclase y subclase.
import javax.swing.JOptionPane;

public class PruebaRelacionJerarquia1 { 

   public static void main( String[] args )
   {
      // asignar a la variable tipo superclase, la referencia a la superclase
      Punto3 punto = new Punto3( 30, 50 );                      

      // asignar a la referencia de la subclase, la variable tipo subclase
      Circulo4 circulo = new Circulo4( 120, 89, 2.7 );         

      // invocar a toString en objeto de superclase usando variable de superclase
      String salida = "Llamar a toString de Punto3 con la referencia a la" +
         " superclase apuntando al objeto de la superclase: \n" + punto.toString();

      // invocar a toString en objeto de subclase usando variable de subclase
      salida += "\n\nLlamar a toString de Circulo4 con la referencia a la" +
         " subclase apuntando al objeto de la subclase: \n" + circulo.toString();

      // invocar a toString en objeto de subclase utilizando variable de superclase
      Punto3 refPunto = circulo;
      salida += "\n\nLlamar a toString de Circulo4 con la referencia a la" +
         " superclase apuntando al objeto de la subclase: \n" + refPunto.toString();

      JOptionPane.showMessageDialog( null, salida );  // mostrar la salida

      System.exit( 0 );

   } // fin de main

} // fin de la clase PruebaRelacionJerarquia1

Descargar código fuente

Herencia de Interfaz y de implementación. Jerarquía Figura->Punto->Criculo->Cilindro

Este ejemplo contiene 5 clases; la primera de ellas es la clase Figura:

// Declaración de la superclase abstracta Figura.

public abstract class Figura extends Object
{

   // devolver el área de la figura; 0.0 de manera predeterminada
   public double obtenerArea()
   {
      return 0.0;
   } 

   // devolver el volumen de la figura; 0.0 de manera predeterminada
   public double obtenerVolumen()
   {
      return 0.0;
   } 

   // método abstracto, sobrescrito por las subclases
   public abstract String obtenerNombre();

} // fin de la clase abstracta Figura

La segunda es la clase Punto:

// Declaración de la clase Punto que hereda de Figura.
public class Punto extends Figura {
   private int x;  // parte x del par de coordenadas
   private int y;  // parte y del par de coordenadas

   // constructor sin argumentos; valor predeterminado de 0 para x e y
   public Punto()
   {
      // la llamada implícita al constructor de Object ocurre aquí
   } 

   // constructor
   public Punto( int valorX, int valorY )
   {
      // la llamada implícita al constructor de Object ocurre aquí
      x = valorX;  // no hay necesidad de validación
      y = valorY;  // no hay necesidad de validación
   } 

   // establecer x en el par de coordenadas
   public void establecerX( int valorX )
   {
      x = valorX;  // no hay necesidad de validación
   } 

   // devolver x del par de coordenadas
   public int obtenerX()
   {
      return x;
   } 

   // establecer y en el par de coordenadas
   public void establecerY( int valorY )
   {
      y = valorY;  // no hay necesidad de validación
   } 

   // devolver y del par de coordenadas
   public int obtenerY()
   {
      return y;
   } 

   // sobrescribir el método abstracto obtenerNombre para devolver "Punto"
   public String obtenerNombre()
   {
      return "Punto";
   } 

   // sobrescribir a toString para devolver la representación String de Punto
   public String toString()
   {
      return "[" + obtenerX() + ", " + obtenerY() + "]";
   } 

} // fin de la clase Punto

La tercera es la clase Circulo:

// La clase Circulo que hereda de Punto.

public class Circulo extends Punto {
   private double radio;  // radio del Circulo

   // constructor sin argumentos; el valor predeterminado de radio es 0.0
   public Circulo()
   {
      // la llamada implícita al constructor de Punto ocurre aquí
   } 

   // constructor
   public Circulo( int x, int y, double valorRadio )
   {
      super( x, y );  // llamar al constructor de Punto
      establecerRadio( valorRadio );
   } 

   // establecer el radio
   public void establecerRadio( double valorRadio )
   {
      radio = ( valorRadio < 0.0 ? 0.0 : valorRadio );
   } 

   // devolver el radio
   public double obtenerRadio()
   {
      return radio;
   } 

   // calcular y devolver el diámetro
   public double obtenerDiametro()
   {
      return 2 * obtenerRadio();
   } 

   // calcular y devolver la circunferencia
   public double obtenerCircunferencia()
   {
      return Math.PI * obtenerDiametro();
   } 

   // sobrescribir el método abstracto obtenerArea para devolver área del Circulo
   public double obtenerArea()
   {
      return Math.PI * obtenerRadio() * obtenerRadio();
   } 

   // sobrescribir el método abstracto obtenerNombre para devolver "Circulo"
   public String obtenerNombre()
   {
      return "Circulo";
   } 

   // sobrescribir toString para devolver la representación String de Circulo
   public String toString()
   {
      return "Centro = " + super.toString() + "; Radio = " + obtenerRadio();
   } 

} // fin de la clase Circulo

La cuarta es la clase Cilindro:

// La clase Cilindro que hereda de Circulo.

public class Cilindro extends Circulo {
   private double altura;  // la altura del Cilindro

   // constructor sin argumentos; el valor predeterminado de altura es 0.0
   public Cilindro()
   {
      // la llamada implícita al constructor de Circulo ocurre aquí
   } 

   // constructor
   public Cilindro( int x, int y, double radio, double valorAltura )
   {
      super( x, y, radio );  // llamar al constructor de Circulo
      establecerAltura( valorAltura );
   } 

   // establecer la altura del Cilindro
   public void establecerAltura( double valorAltura )
   {
      altura = ( valorAltura < 0.0 ? 0.0 : valorAltura );
   } 

   // obtener la altura del Cilindro
   public double obtenerAltura()
   {
      return altura;
   } 

   // sobrescribir método abstracto obtenerArea para devolver area de Cilindro
   public double obtenerArea()
   {
      return 2 * super.obtenerArea() + obtenerCircunferencia() * obtenerAltura();
   } 

   // sobrescribir método abstracto obtenerVolumen para devolver valor del Cilindro
   public double obtenerVolumen()
   {
      return super.obtenerArea() * obtenerAltura();
   } 

   // sobrescribir método abstracto obtenerNombre para devolver "Cilindro"
   public String obtenerNombre()
   {
      return "Cilindro";
   } 

   // sobrescribir toString para devolver representación String del Cilindro
   public String toString()
   {
      return super.toString() + "; Altura = " + obtenerAltura();
   } 

} // fin de la clase Cilindro

La quinta es la clase PruebaHerenciaAbstracta, que contiene el mértodo main:

// Controlador para la jerarquía figura, punto, circulo, cilindro.
import java.text.DecimalFormat;
import javax.swing.JOptionPane;

public class PruebaHerenciaAbstracta {

   public static void main( String args[] )
   {
      // establecer el formato de número de punto flotante
      DecimalFormat dosDigitos = new DecimalFormat( "0.00" );

      // crear objetos Punto, Circulo y Cilindro
      Punto punto = new Punto( 7, 11 );
      Circulo circulo = new Circulo( 22, 8, 3.5 );
      Cilindro cilindro = new Cilindro( 20, 30, 3.3, 10.75 );  

      // obtener nombre  y representación de cadena de cada objeto
      String salida = punto.obtenerNombre() + ": " + punto + "\n" +
         circulo.obtenerNombre() + ": " + circulo + "\n" +
         cilindro.obtenerNombre() + ": " + cilindro + "\n";

      Figura arregloDeFiguras[] = new Figura[ 3 ];  // crear arreglo de Figuras

      // apuntar arregloDeFiguras[ 0 ] al objeto de la subclase Punto
      arregloDeFiguras[ 0 ] = punto;

      // apuntar arregloDeFiguras[ 1 ] al objeto de la subclase Circulo
      arregloDeFiguras[ 1 ] = circulo;

      // apuntar arregloDeFiguras[ 2 ] al objeto de la subclase Cilindro
      arregloDeFiguras[ 2 ] = cilindro;

      // iterar a través de arregloDeFiguras para obtener nombre, representación
      // de cadena, área y volumen para cada Figura en el arreglo
      for ( int i = 0; i < arregloDeFiguras.length; i++ ) {
         salida += "\n\n" + arregloDeFiguras[ i ].obtenerNombre() + ": " +
            arregloDeFiguras[ i ].toString() + "\nArea = " +
            dosDigitos.format( arregloDeFiguras[ i ].obtenerArea() ) +
            "\nVolumen = " +
            dosDigitos.format( arregloDeFiguras[ i ].obtenerVolumen() );
      }

      JOptionPane.showMessageDialog( null, salida );  // mostrar resultados

      System.exit( 0 );

   } // fin de main

} // fin de la clase PruebaHerenciaAbstracta

Descargar código fuente

Utilización de clases internas para el manejo de eventos

este ejemplo posee 2 clases; la primera es la clase Tiempo:

// Declaración de la clase Tiempo con métodos establecer y obtener.
import java.text.DecimalFormat;  

public class Tiempo
{
   private int hora;     // 0 - 23
   private int minuto;   // 0 - 59
   private int segundo;   // 0 - 59

   // un objeto de formato para compartir en toString y aStringUniversal
   private static DecimalFormat dosDigitos = new DecimalFormat( "00" );

   // el constructor de Tiempo inicializa cada variable de instancia en cero;
   // se asegura que cada objeto Tiempo inicie en un estado consistente
   public Tiempo()
   {
      this( 0, 0, 0 ); // invocar al constructor de Tiempo con tres argumentos
   }

   // constructor de Tiempo: se proporciona hora; minuto y segundo con valor predeterminado de 0
   public Tiempo( int h )
   {
      this( h, 0, 0 ); // invocar al constructor de Tiempo con tres argumentos
   }

   // constructor de Tiempo: se proporcionan hora y minuto, segundo con valor predeterminado de 0
   public Tiempo( int h, int m )
   {
      this( h, m, 0 ); // invocar al constructor de Tiempo con tres argumentos
   }

   // constructor de Tiempo: se proporcionan hora, minuto y segundo
   public Tiempo( int h, int m, int s )
   {
      establecerTiempo( h, m, s );
   }

   // constructor de Tiempo: se suministra otro objeto Tiempo3
   public Tiempo( Tiempo tiempo )
   {
      // invocar al constructor de Tiempo con tres argumentos
      this( tiempo.obtenerHora(), tiempo.obtenerMinuto(), tiempo.obtenerSegundo() );
   }

   // Métodos Establecer
   // establecer un nuevo valor de tiempo, utilizando la hora universal; realizar
   // comprobaciones de validez en los datos; establecer valores inválidos en cero
   public void establecerTiempo( int h, int m, int s )
   {
      establecerHora( h );   // establecer la hora
      establecerMinuto( m ); // establecer el minuto
      establecerSegundo( s ); // establecer el segundo
   }

   // validar y establecer hora
   public void establecerHora( int h )
   {
      hora = ( ( h >= 0 &amp;&amp; h < 24 ) ? h : 0 );
   }

   // validar y establecer minuto
   public void establecerMinuto( int m )
   {
      minuto = ( ( m >= 0 &amp;&amp; m < 60 ) ? m : 0 );
   }

   // validar y establecer segundo
   public void establecerSegundo( int s )
   {
      segundo = ( ( s >= 0 &amp;&amp; s < 60 ) ? s : 0 );
   }

   // Métodos Obtener
   // obtener valor de hora
   public int obtenerHora()
   {
      return hora;
   }

   // obtener valor de minuto
   public int obtenerMinuto()
   {
      return minuto;
   }

   // obtener valor de segundo
   public int obtenerSegundo()
   {
      return segundo;
   }

   // convertir a String en formato de hora universal
   public String aStringUniversal()
   {
      return dosDigitos.format( obtenerHora() ) + ":" +
         dosDigitos.format( obtenerMinuto() ) + ":" +
         dosDigitos.format( obtenerSegundo() );
   }

   // convertir a String en formato de hora estándar
   public String toString()
   {
      return ( ( obtenerHora() == 12 || obtenerHora() == 0 ) ?
         12 : obtenerHora() % 12 ) + ":" + dosDigitos.format( obtenerMinuto() ) +
         ":" + dosDigitos.format( obtenerSegundo() ) +
         ( obtenerHora() < 12 ? " AM" : " PM" );
   }

} // fin de la clase Tiempo

Y la segunda es la clase VentanaPruebaTiempo, que contiene el método main:

// Declaraciones de clase interna utilizadas para crear manejadores de eventos.
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

public class VentanaPruebaTiempo extends JFrame
{
   private Tiempo tiempo;
   private JLabel horaEtiqueta, minutoEtiqueta, segundoEtiqueta;
   private JTextField horaCampo, minutoCampo, segundoCampo, pantallaCampo;
   private JButton salirBoton;

   // configurar GUI
   public VentanaPruebaTiempo()
   {
      // llamar al constructor de JFrame para establecer cadena de barra de título
      super( "Demostración de clase interna" );  

      tiempo = new Tiempo();  // crear objeto Tiempo

      // usar método heredado getContentPane para obtener panel de contenido de la ventana
      Container contenedor = getContentPane();
      contenedor.setLayout( new FlowLayout() );  // cambiar esquema

      // preparar horaEtiqueta y horaCampo
      horaEtiqueta = new JLabel( "Ajuste hora" );
      horaCampo = new JTextField( 10 );
      contenedor.add( horaEtiqueta );
      contenedor.add( horaCampo );

      // preparar minutoEtiqueta y minutoCampo
      minutoEtiqueta = new JLabel( "Ajuste minuto" );
      minutoCampo = new JTextField( 10 );
      contenedor.add( minutoEtiqueta );
      contenedor.add( minutoCampo );

      // preparar segundoEtiqueta y segundoCampo
      segundoEtiqueta = new JLabel( "Ajuste segundo" );
      segundoCampo = new JTextField( 10 );
      contenedor.add( segundoEtiqueta );
      contenedor.add( segundoCampo );

      // establecer pantallaCampo
      pantallaCampo = new JTextField( 30 );
      pantallaCampo.setEditable( false );
      contenedor.add( pantallaCampo );

      // establecer salirBoton
      salirBoton = new JButton( "Salir" );
      contenedor.add( salirBoton );

      // crear una instancia de la clase interna ActionEventHandler
      ActionEventHandler manejador = new ActionEventHandler();

      // registrar manejadores de eventos; el objeto referenciado por manejador
      // es el ActionListener, el cual contiene el método actionPerformed
      // que será llamado para manejar los eventos de acción generados por
      // horaCampo, minutoCampo, segundoCampo y salirBoton
      horaCampo.addActionListener( manejador );
      minutoCampo.addActionListener( manejador );
      segundoCampo.addActionListener( manejador );
      salirBoton.addActionListener( manejador );

   } // fin del constructor

   // mostrar tiempo en pantallaCampo
   public void mostrarTiempo()
   {
      pantallaCampo.setText( "La hora es: " + tiempo );
   }

   // iniciar aplicación: crear, ajustar tamaño y mostrar VentanaPruebaTiempo;
   // cuando main termina, el programa continua ejecutándose ya que
   // se muestra una ventana mediante las instrucciones en main
   public static void main( String args[] )
   {
      VentanaPruebaTiempo ventana = new VentanaPruebaTiempo();

      ventana.setSize( 400, 140 );
      ventana.setVisible( true );

   } // fin de main

   // declaración de clase interna para manejar eventos JTextField y JButton
   private class ActionEventHandler implements ActionListener {

      // método para manejar eventos de acción
      public void actionPerformed( ActionEvent evento )
      {
         // el usuario oprimió salirBoton
         if ( evento.getSource() == salirBoton )
            System.exit( 0 );   // terminar la aplicación

         // el usuario oprimió tecla Intro en horaCampo
         else if ( evento.getSource() == horaCampo ) {
            tiempo.establecerHora( Integer.parseInt(
               evento.getActionCommand() ) );
            horaCampo.setText( "" );
         }

         // el usuario oprimió tecla Intro en minutoCampo
         else if ( evento.getSource() == minutoCampo ) {
            tiempo.establecerMinuto( Integer.parseInt(
               evento.getActionCommand() ) );
            minutoCampo.setText( "" );
         }

         // el usuario oprimió tecla Intro en segundoCampo
         else if ( evento.getSource() == segundoCampo ) {
            tiempo.establecerSegundo( Integer.parseInt(
               evento.getActionCommand() ) );
            segundoCampo.setText( "" );
         }

         mostrarTiempo();  // llamar a un método de la clase externa

      } // fin del método actionPerformed

   } // fin de la clase interna ActionEventHandler

} // fin de la clase VentanaPruebaTiempo

Descargar código fuente

Utilización de clases internas anónimas para el manejo de eventos

este ejemplo posee 2 clases; la primera es la clase Tiempo (que es la misma del anterior ejemplo); y la segunda es la clase VentanaPruebaTiempo2, que contiene el método main:

// Demostración de los métodos establecer y obtener de la clase Tiempo
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

public class VentanaPruebaTiempo2 extends JFrame {
   private Tiempo tiempo;
   private JLabel horaEtiqueta, minutoEtiqueta, segundoEtiqueta;
   private JTextField horaCampo, minutoCampo, segundoCampo, pantallaCampo;

   // constructor
   public VentanaPruebaTiempo2()
   {
      // llamar al constructor de JFrame para establecer cadena de barra de título
      super( "Demostración de clase interna anónima" );  

      tiempo = new Tiempo();        // crear objeto Tiempo
      crearGUI();              // configurar GUI
      registrarManejadoresDeEventos();  // configurar el manejo de eventos
   }

   // crear componentes de GUI y adjuntarlos al panel de contenido
   private void crearGUI()
   {
      Container contenedor = getContentPane();
      contenedor.setLayout( new FlowLayout() );

      horaEtiqueta = new JLabel( "Ajuste hora" );
      horaCampo = new JTextField( 10 );
      contenedor.add( horaEtiqueta );
      contenedor.add( horaCampo );

      minutoEtiqueta = new JLabel( "Ajuste minuto" );
      minutoCampo = new JTextField( 10 );
      contenedor.add( minutoEtiqueta );
      contenedor.add( minutoCampo );

      segundoEtiqueta = new JLabel( "Ajuste segundo" );
      segundoCampo = new JTextField( 10 );
      contenedor.add( segundoEtiqueta );
      contenedor.add( segundoCampo );

      pantallaCampo = new JTextField( 30 );
      pantallaCampo.setEditable( false );
      contenedor.add( pantallaCampo );

   } // fin del método crearGUI

   // registrar manejadores de eventos para horaCampo, minutoCampo y segundoCampo
   private void registrarManejadoresDeEventos()
   {
      // registrar manejador de eventos para horaCampo
      horaCampo.addActionListener( 

         new ActionListener() {  // clase interna anónima

            public void actionPerformed( ActionEvent evento )
            {
               tiempo.establecerHora( Integer.parseInt(
                  evento.getActionCommand() ) );
               horaCampo.setText( "" );
               mostrarTiempo();
            }

         } // fin de la clase interna anónima

      ); // fin de la llamada a addActionListener para horaCampo

      // registrar manejador de eventos para minutoCampo
      minutoCampo.addActionListener( 

         new ActionListener() {  // clase interna anónima

            public void actionPerformed( ActionEvent evento )
            {
               tiempo.establecerMinuto( Integer.parseInt(
                  evento.getActionCommand() ) );
               minutoCampo.setText( "" );
               mostrarTiempo();
            }

         } // fin de la clase interna anónima

      ); // fin de la llamada a addActionListener para minutoCampo

      segundoCampo.addActionListener( 

         new ActionListener() {  // clase interna anónima

            public void actionPerformed( ActionEvent evento )
            {
               tiempo.establecerSegundo( Integer.parseInt(
                  evento.getActionCommand() ) );
               segundoCampo.setText( "" );
               mostrarTiempo();
            }

         } // fin de la clase interna anónima

      ); // fin de la llamada a addActionListener para segundoCampo

   } // fin del método registrarManejadoresDeEventos

   // mostrar tiempo en pantallaCampo
   public void mostrarTiempo()
   {
      pantallaCampo.setText( "La hora es: " + tiempo );
   }

   // crear objeto VentanaPruebaTiempo2, registrarse para sus eventos de ventana
   // y mostrarlo para empezar la ejecución de la aplicación
   public static void main( String args[] )
   {
      VentanaPruebaTiempo2 ventana = new VentanaPruebaTiempo2();

      // registrar componente de escucha para evento windowClosing
      ventana.addWindowListener(

         // clase interna anónima para evento windowClosing
         new WindowAdapter() {

            // terminar la aplicación cuando el usuario cierra la ventana
            public void windowClosing( WindowEvent evento )
            {
               System.exit( 0 );
            }

         } // fin de la clase interna anónima

      ); // fin de la llamada a addWindowListener para ventana

      ventana.setSize( 400, 120 );
      ventana.setVisible( true );

   } // fin de main

} // fin de la clase VentanaPruebaTiempo2

Descargar código fuente

Los ejercicios utilizados en este post están basados en ejemplos del libro Cómo programar en Java de Deitel, y por lo tanto están bajo la licencia que esta editorial disponga.

13 Comentarios | deja el tuyo

Un enlace entrante

12 Comentarios en “[código] Programación Orientada a Objetos: Polimorfismo (1)”

  1. javier dice:

    muy buenos ejemplos

  2. Roberto dice:

    Gracias, en realidad los ejemplos son muy ilsutrativos

  3. klosxx dice:

    Asuu q buenos ejercicios poco a poco se siente la dificultad

  4. ronald dice:

    ta xvre los codigos weno me gustaria k me ayudes hacer un programa para una ferreteria me falta algunos detalles

  5. gerson dice:

    grax broder por os codigos, ya que empiezo la carrera de ISC me son muy utiles espero sigan publicando mas codigos, GRAX carnal

  6. Mario dice:

    lo que miro no es polimorfismo es herencia

  7. jose ignacio dice:

    pienso lo mismo que mario……

  8. Cirilo dice:

    muy buenos ejemplos los analizaré para corroborar si realmente aplica polimorfismo o solo herencia

  9. jere dice:

    si yo opino lo mismo que trata de herencia aunque muy buenos ejemplos

  10. DEYSI dice:

    GRACIAS SON MUY BUENOS EJEMPLOS

  11. jan dice:

    se ven muy buenos esos ejercicios,fata ejecutarlos nomas……

  12. FERRRRR dice:

    AMIGO QUE PACIENCIA TIENES PARA COPIAR LOS CODIGOS DEL LIBRO DEITEL Y DEITEL QUINTA EDICION.. SALUDOS

¡Déjanos tu comentario!