La POO (Programación Orientada a Objetos)


Crear software en forma rápida, correcta y económica sigue siendo un objetivo difícil de alcanzar en una época en que la demanda de software nuevo y más poderoso va en aumento. Los objetos, o dicho en forma más precisa las clases de las que provienen los objetos, son en esencia componentes de software reutilizables. Existen objetos de fecha, objetos de hora, objetos de audio, objetos de video, objetos de automóviles, objetos de personas, etcétera. Casi cualquier sustantivo se puede representar de manera razonable como un objeto de software en términos de sus atributos (como el nombre, color y tamaño) y comportamientos (por ejemplo, calcular, moverse y comunicarse). Los desarrolladores de software han descubierto que al usar una metodología de diseño e implementación orientada a objetos y modular, pueden crea grupos de desarrollo de software más productivos de lo que era posible con las técnicas populares anteriores, como la “programación estructurada”; por lo general los programas orientados a objetos son más fáciles de comprender, corregir y modificar. Al igual que las muñecas rusas llamada Matrioska, es la estructura de la clases con sus objetos, métodos, atributos, declaraciones, expresiones y operaciones.




Para ayudarle a comprender los objetos y su contenido, empecemos con una analogía simple. Supon que desea conducir un auto y hacer que vaya más rápido al oprimir el pedal del acelerador. ¿Qué debe ocurrir para que pueda hacer esto? Bueno, antes de que pueda conducir un auto, alguien tiene que diseñarlo. Por lo general, un auto empieza en forma de dibujos de ingeniería, similares a los planos de construcción que describen el diseño de una casa. Estos dibujos de ingeniería incluyen el diseño del pedal del acelerador.

El pedal oculta los complejos mecanismos que se encargan de que el auto aumente su velocidad, de igual forma que el pedal del freno oculta los mecanismos que disminuyen la velocidad del auto y el volante “oculta” los mecanismos que hacen que el auto de vuelta. Esto permite que las personas con poco o nada de conocimiento acerca de cómo funcionan los motores, los frenos y los mecanismos de la dirección puedan conducir un auto con facilidad.


Por desgracia, así como no es posible cocinar en la cocina de un plano de construcción, tampoco es posible conducir los dibujos de ingeniería de un auto. Antes de poder conducir un auto, éste debe construirse a partir de los dibujos de ingeniería que lo describen. Un auto completo tendrá un pedal acelerador verdadero para hacer que aumente su velocidad, pero aún así no es suficiente; el auto no acelerará por su propia cuenta (¡esperemos que así sea!), así que el conductor debe oprimiré. E1 pedal del acelerador para aumentar la velocidad del auto.

Java es un lenguaje poderoso. Algunas veces, los programadores experimentados se enorgullecen de su capacidad para usar el lenguaje de manera extraña, contorsionada, y compleja. ésta es una pobre práctica de programación. Hace que los programas sean más difíciles de leer, más propensos a comportarse de manera extraña, más difíciles de depurar y probar, y más difíciles de adaptar a los requerimientos cambiantes.

La "POO" hace imitación al mundo fisico, porque son reutilizables y comprensibles.


JAVA:

1) Organiza los programas llamados CLASES

2) Las clases son para crear OBJETOS.

3) La DEFINICION de la clase por COPORTAMIENTO Y ATRIBUTOS

4) Conectar las CLASES mediante HERENCIAS

5) Enlazar clases mediante Paquetes e Intrefaces.


La POO se centra en "tareas",


Las CLASES y OBJETOS crean PROGRAMAS.
Podemos comparar esto como un componente, es decir si necesitamos tener un "Equipo de música" podemos tener todos los componentes en uno solo, pero si queremeos tener en si un equipo de música debemos ir selecionando los componentes de forma individual e ir "armando" lo que mejor nos agrade, es decir, quiero un componente de un reproductor de DVD /Blue Ray, un amplificador de una marca especifica porque tiene unas "caracteristicas" que me interesa, unas Bocinas con ciertas propiedades, etc, y asi ir formando lo que necesitamos y queremos y no algo que ya esta diseñado y no puedeo agregar "algo" que me interesaria.

La creación de un objeto a partir de una clase se llama también instancia, por lo que los objetos se consideran instanciados

Los OBJETOS se relacionan entre sí por medio de métodos

La instanciación puede tener características diferentes

Desde la versión 5 de Java, se convierte automáticamente entre las clases envoltorios y sus correspondientes tipos básicos.

● Si se introduce un tipo básico donde se espera un objeto de una clase envoltorio, se llama al constructor correspondiente (boxing).

● Si se introduce un objeto de una clase envoltorio donde se espera un tipo básico, se llama al método de acceso correspondiente (unboxing).

           

Tipo básico

Clase envoltorio

int Integer
char Character
boolean Boolean
long Long
double Double
float Float
short Short
byte Byte

Haremos un programa que muestre una clase con sus instancias y un método (en otros lenguajes de programación se le conoce como subrutina), comenzaremos creando la clase robot, (simulemos un robot que debe de estar censando la temperatura, y que en ciertas condiciones deberá de regresar por que el calor es excesivo y evitar daños a sus componentes)

iniciemos con la clase e instanciemos sus variables:



esto nos identifica 3 variables que están siendo instanciadas dentro de la clase creada con el nombre de Robot. y el método llamado comprobarTemperatura() será solicitada (llamada) en cualquier momento para verificar la temperatura y evaluar esta.



creamos otro método y este es para "ver" los atributos de las instancias

void mostrarAtributos (){ //se crea otro metodo de instancia, mostrando los atributos
                                       // de la instancia
    System.out.println("Status de la Mision "+status);
    System.out.println("Temperatura del entorno "+temperatura);
    System.out.println("Velocidad para retorno "+velocidad);
}

Resumiendo, esta parte se ha creado una clase llamada Robot, y tenemos instanciadas 3 Variables, y 2 métodos de esa clase:



Pasamos al tercer método (public static void main(String[] args) esto se conce como método main) donde decalramos la clase main que es necesaria para ejecutar el programa:




Sobre la clase creada anteriormente (Robot) creamos un objeto (yoRobot) que contendra las propiedades y atributos de la clase Robot, new Robot(); realiza la llamada a la clase para asignar el objeto (yoRobot) las propiedades de dicha clase.

El resultado de este programa es lo siguiente:



Observa lo que resulta y sigue los pasos que se muestran como resultado y sigue la secuencia del programa:

package robot;

/**
 *
 * @author Miguel
 */
public class Robot {
String status;   //Estas son 3 variables instancia
int velocidad;   //3 atributos de la clase
float temperatura;
                                                  // lo que sigue es declaracion de un metodo
void comprobarTemperatura (){ // el metodo contiene las acciones a seguir cuando es llamada
                                                 // desde cualquier lugar del programa
    if (temperatura > 660){
        status ="Volviendo a Casa";
        velocidad =5;
    }
}
void mostrarAtributos (){ //se crea otro metodo de instancia, mostrando los atributos
                                       // de la instancia
    System.out.println("Status de la Mision "+status);
    System.out.println("Temperatura del entorno "+temperatura);
    System.out.println("Velocidad para retorno "+velocidad);
}
    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) { // se considera como metodo de la clase main
       Robot yoRobot = new Robot();      // la clase es Robot, yoRobot es el nombre asociado (es el objeto)
                                                             // new Robot() es la llamada a la clase con la asignacion del objeto
       yoRobot.status = "explorando";
       yoRobot.velocidad = 2;
       yoRobot.temperatura = 550;
                                                           // en base al objeto instanciado para clase robot se asignan al objeto los 3 atributos que se
                                                           // declararon a la clase Robot

       yoRobot.mostrarAtributos();          // se realiza una llamda al metodo mostrarAtributos por medio
                                                           // del objeto yoRobot
       System.out.println("Aumentado velocidad a 3");    //mostrando cambio de velocidad
       yoRobot.velocidad = 3;                                        // cambiando el valor del objeto con el atributo de
                                                                                    // velocidad
       System.out.println("Cambiando la Temperatura 670"); // mostrando cambio de temperatura
       yoRobot.temperatura = 670;                                      // cambio de valor del objeto con el atributo
                                                                                        // temperatura a 670 esta por arriba del valor limite
       yoRobot.comprobarTemperatura();                           // llama al método para verificar la temperatura
      
       yoRobot.mostrarAtributos();                                     // solicita los atributos del objeto para "ver" estos atributos.
      
      
    }   
}

Jerarquia de Clases y Herencia

Al crear una clase, en lugar de declarar miembros en cada oportunidad de instanciamiento completamente nuevos (es decir crear variables en cada vez que se requieren, se hace uso de la herencia para evitar estar escribiendo constanatemente nuevas variables y/o metodos), el programador puede designar que la nueva clase que herede a los miembros de una existente. La cual se conoce como superclase, y la clase nueva como subclase. (El lenguaje de programación C++ se refiere a la superclase como la clase base, y a la subclase como clase derivada.). Cada subclase puede convertirse en la superclase de futuras subclases.

Una subclase puede agregar sus propios campos y métodos. Por lo tanto, una subclase es más específica que su superclase y representa a un grupo más especializado de objetos. La subclase exhibe los comportamientos de su superclase y puede modificarlos, de modo que operen en forma apropiada para la subclase. Es por ello que a la herencia se le conoce algunas veces como especialización.

La superclase directa es la superclase a partir de la cual la subclase hereda en forma explícita.

Una superclase indirecta es cualquier clase arriba de la superclase directa en la jerarquía de bases, que define las relaciones de herencia entre las clases. En Java, la jerarquía de clases empieza con la clase Object (en el paquete java.lang), a partir de la cual se extienden (o “heredan”) todas las clases en Java, ya sea en forma directa o indirecta.

Java, sólo soporta la herencia simple, en donde cada clase se deriva sólo de una superclase directa. A diferencia de C++, Java no soporta la herencia múltiple (que ocurre cuando una clase se deriva de más de una superclase directa).



En la jerarquia de las clases Java se encuentra la clase Object. (Superclase) de la que se heredan las subclases











Es necesario hacer una diferencia entre la relación es un y la relación tiene un. La relación es un representa a la herencia. En este tipo de relación, un objeto de una subclase puede tratarse también como un objeto de su superclase. Por ejemplo, un auto es un vehículo. En contraste, la relación tiene un representa la composición. En este tipo de relación, un objeto contiene referencias a objetos como miembros. Por ejemplo, un auto tiene un volante de dirección (y un objeto auto tiene una referencia a un objeto volante de dirección).

Las clases nuevas pueden heredar de las clases en las bibliotecas de clases. Las organizaciones desarrollan sus propias bibliotecas de clases y pueden aprovechar las que ya están disponibles en todo el mundo. Es probable que algún día, la mayoría de software nuevo se construya a partir de componentes reutilizables estandarizados, como sucede actualmente con la mayoría de los automóviles y del hardware de computadora. Esto facilitará el desarrollo de software más poderoso, abundante y económico.

Solo hay herencia simple, no hay herencia multiple.

Superclases y subclases.- A menudo, un objeto de una clase es un objeto de otra clase también.

Una interface es una colección de métodos que pueden ser usados por una clase. (solo son definidos mas no implementados).

Los paquetes son modos de agrupar clases e interfaces relacionadas.

La palabra reservada import

Para importar clases de un paquete se usa el comando import.

Paquete Descripción
java.applet Contiene las clases necesarias para crear applets que se ejecutan en la ventana del navegador
java.awt Contiene clases para crear una aplicación GUI independiente de la plataforma
java.io Entrada/Salida. Clases que definen distintos flujos de datos
java.lang Contiene clases esenciales, se importa impícitamente sin necesidad de una sentencia import.
java.net Se usa en combinación con las clases del paquete java.io para leer y escribir datos en la red.
java.util Contiene otras clases útiles que ayudan al programador

Hemos usado la instrucción System.out.println, esta proviene de una libreria que se usa para los elementos indispensables de la programación Java, aunque no hemos incluido la biblioteca java.lang. que es la que contiene la instrución para realizar System.out.println, este se encuentra por defecto y no es necesaria llamarla de forma explicita, pero algunas bibliotecas si es necesario utilizarlas, es menester conocer estas blibliotecas.

Se puede importar una clase individual como  import java.awt.Font; o bien, se puede importar las clases declaradas públicas de un paquete completo, utilizando un arterisco (*) para reemplazar los nombres de clase individuales tal como: import java.awt.*;

La clase System proporciona una interface a una serie de recursos del sistema, entre ellos se encuentran los de entrada y salida del sistema, System.in y System.out.

Los constructores llaman por defecto al constructor de la clase superior a través de una llamada a super() (en este caso al constructor por defecto). Esto es debido a que los constructores no se heredan entre jerarquías de clases. Por lo tanto la palabra super() siempre es la primera línea de un constructor e invoca al constructor de la clase superior que comparta el mismo tipo de parametrización.

Aunque nosotros no pongamos la palabra super() esta siempre será añadida salvo que nosotros la añadamos.

La otra posibilidad a super() es el uso de this() en la primera linea de un constructor. Esto lo que hace es invocar a otro constructor que este en la misma clase y que soporte el conjunto de parámetros que le pasamos.

Creacion de Objetos

Tambien se le conocen a los objetos como Instancias.

Ejemplos de objetos:


String nombre = new String();  // es un objeto, se observa la apalabra clave NEW, debera de tener un parentesis, esto es importante es un objeto de la clase String

URL direccion = new URL("http://www.cursojava.net"); // aqui el parentesis tiene un valor para ser instanciado, esto significa que el parentesis puede ser o no vacio, es un objeto de la clase URL

DeltaRobotR2 = new DeltaRobot(); //es un objeto de la clase DeltaRobot

En resumen el objeto se crea cuando se usa la palabra clave NEW

La Herencia es uno de los 4 pilares de la programación orientada a objetos (POO) junto con la Abstracción, Encapsulación y Polimorfismo. Al principio cuesta un poco entender estos conceptos característicos del paradigma de la POO porque solemos venir de otro paradigma de programación como el paradigma de la programación estructurada, pero se ha de decir que la complejidad está en entender este nuevo paradigma y no en otra cosa.

Respecto a la herencia se han dado muchas definiciones como por ejemplo la siguiente:

"La herencia es un mecanismo que permite la definición de una clase a partir de la definición de otra ya existente. La herencia permite compartir automáticamente métodos y datos entre clases, subclases y objetos."

Así de primera instancia esta definición es un poco difícil de digerir para aquellos que estan empezando con la POO, así que vamos a intentar digerir esta definición con un ejemplo en el que veremos que la herencia no es más que un "Copy-Paste Dinámico" "Copiar - Pegar dinamico" o bien de esta otra forma de "sacar factor común" al código que escribimos.

Para declarar la herencia en Java usamos la palabra clave extends. Ejemplo: public class MiClase2 extends Miclase1. Para familiarizarte con la herencia te proponemos que escribas y estudies un pequeño programa donde se hace uso de ella. Escribe el código de las clases que mostramos a continuación.

Primero declaramos la parte de main y dandos el nombre de Herencia1





A pesar que este proyecto podrá presentar errores, sigue con el ejemplo ten cuidado de los ( ) comas,  punto y coma. A continuación creamos las clases que van a intervenir, es decir haremos las clases en archivos independientes pero al compilar estas están en el mismo proyecto, asi que se consideran estas, usando New File, del menú :






Observa que mientra se genera la nueva clase se hace referencia a package herencia1, del Proyecto Herencia1, que se instancio al comienzo.

debera de presentarse 2 ventanas y con este aspecto:

Ventana de Herencia1:

Se presenta un error porque aún no hemos compleatdo todo el proceso de herencia:



Y la clase Persona:



Modificamos la clase Persona:



Has de observar que hemos agregado la palabra private antes de declaracion de la variable.

Hemos declarado variables de tipo primitivo u objeto usando la sintaxis private tipoElegido nombreVariable;

La palabra clave private es un indicador de en qué ámbito del programa va a estar disponible la variable. Supón que el programa es un edificio con gente trabajando y que hay elementos en el edificio, por ejemplo una impresora, que pueden tener un uso: individual para una persona, colectivo para un grupo de personas, colectivo para todas las personas de una planta, colectivo para todas las personas de un departamento aunque estén en varias plantas, o colectivo para todo el edificio.

Pues bien, las variables en Java van a quedar disponibles para su uso en ciertas partes del programa según especifiquemos con las palabras clave public, private, protected, package, etc.

Lo veremos más adelante, ahora simplemente nos interesa ver cómo declarar variables y usaremos de forma preferente la palabra clave private.

El hecho de declarar una variable implica que se reserva un espacio de memoria para ella, pero no que ese espacio de memoria esté ocupado aunque pueda tener un contenido por defecto. Ten en cuenta que en Java no puedes aplicar algunas normas que rigen en otros lenguajes, como que al declarar una variable entera ésta contendrá por defecto el valor cero. En Java esta situación puede dar lugar a errores de compilación: una variable entera no debemos suponer que contenga nada. Para que contenga algo debemos asignarle un contenido.

Descripción del codigo anterior (es la clase para crear la herencia)

/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package herencia1;

/**
 *
 * @author Miguel
 */
public class Persona {  //definimos el nombre de la clase, esta sera la superclase (o clase principal de la que se deriva la herencia)
 private String nombre;  //se instancian las variables de esta clase con la propiedad private
 private String apellidos;
 private int edad;

// Iniciamos el constructor
 public Persona (String nombre,String apellidos,int edad) {
        this.nombre = nombre;
        this.apellidos = apellidos;
        this.edad = edad; }
//metodos
public String getNombre(){return nombre;}     // método de la forma get, es para tomar el nombre de una variable desde la clase
public String getApellidos(){return apellidos;} // método de la forma get, es para tomar el nombre de una variable desde la clase
public int getEdad(){return edad;}                   // método de la forma get, es para tomar el nombre de una variable desde la clase
} // cierre de la clase Persona

Significado de return.

El uso del vocablo return no es obligatorio en la gran mayoría de métodos definidos en Java, sin embargo, tiene dos usos principales:

Primeramente es una manera de indicar que el método en cuestión ha terminado.

Cuando en determinado método se manipula más de una instancia/primitivo del mismo tipo que será retornado, se emplea el vocablo return para evitar ambigüedad.

Cada clase que se declare puede proporcionar un método especial llamado constructor, el cual puede utilizarse para inicializar un objeto de una clase al momento de crearlo. De hecho, Java requiere una llamada al constructor para cada objeto que se crea.

La palabra clave new solicita memoria del sistema para almacenar un objeto, y después llama al constructor de la clase correspondiente para inicializar el objeto. La llamada se indica mediante el nombre de la clase, seguido de paréntesis. Un constructor debe tener el mismo nombre que la clase.

Creamos otra clase que se llamara Profesor (que sera la subclase, es decir la que hereda de la clase Persona), usaremos el mismo método para esto New Class Java:





La clase Profesor y la modificamos de esta manera:



De igual forma conserva package herencia1;

(hay una instruccion llamada super en el siguiente capitulo se extrinde la explicación, pero se requiere aquí, para entender la herencia)

Aqui el codigo:

package herencia1;
/**
 * @author Miguel
 */
// subclase de la super clase Persona
public class Profesor extends Persona{ //extends es para indicar que es una subclase de Persona (tambien podemos decir que es una clase derivada de Persona)
     //Campos específicos de la subclase.
    private String IdProfesor;
    //Constructor de la subclase: incluimos como parámetros al menos los del
    // constructor de la superclase
    public Profesor (String nombre,String apellidos,int edad){
        super(nombre,apellidos,edad) ; //hace referencia para modificar la superclase y agrega propiedades se vera con mas detalle en el siguiente capitulo 4
        IdProfesor = "Desconocido";
    }// cierre del constructor
    //Métodos específicos de la subclase
    public void setIdProfesor(String IdProfesor){this.IdProfesor=IdProfesor;}
    public String getIdProfesor(){return IdProfesor;}
    public void mostrarNombreApellidosYCarnet(){
         // si damos nombre = "Miguel"; si accedemos directamente a un campo privado de la superclase,
         // salta un error. Pero si podemos acceder a variables instanciadas a través de los métodos
         // de acceso público de la superclase
         System.out.println("Nombre Profesor :"+getNombre()+" "+getApellidos()+ " "+"Id de Profesor " //observar la forma de solicitar los metodos
                 +getIdProfesor());                                                                                                               // getNombre() getApellido() getIdProfesor()
    }                                                                                                                                                     // no olvidar el ( )
} //Cierre de clase

Y por ultimo el codigo de la clase main:



El codigo es el siguiente:

/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package herencia1;
/* @author Miguel


       /**
     * @param args the command line arguments
     */
public class Herencia1{
public static void main(String[] args) {
     Profesor profesor1 = new Profesor ("Miguel", "Santos Montoya", 55); //se crea un objeto llamado profesor1 para la clase Profesor y los argumentos pasan a la clase
        profesor1.setIdProfesor("Prof 22-387-11");   // al objeto (profesor1) se le asigna el IdProfesor a travez del metodo setIdProfesor
        profesor1.mostrarNombreApellidosYCarnet(); // llama al metodo mostrarNombreApellidosYCarnet() para mostrar las variables pasadas por herencia.
}
}

De esta manera puede crearse varios objetos con diferentes valores sin necesidad de declarar mas variables y complicando el programa, el hecho de la clase Persona es el que proporciona la "FORMA" de herencia para que los objetos tengan esa misma "forma" y aprobechar la POO.

Los aspectos a destacar del código son:

a) La clase persona es una clase “normal” definida tal y como lo venimos haciendo habitualmente mientras que la clase Profesor es una subclase de Persona con ciertas peculiaridades.

b) Los objetos de la subclase van a tener campos nombre, apellidos y edad (heredados de Persona) y un campo específico IdProfesor. El constructor de una subclase ha de llevar obligatoriamente como parámetros al menos los mismos parámetros que el constructor de la superclase.

c) El constructor de la subclase invoca al constructor de la superclase. Para ello se incluye, obligatoriamente, la palabra clave super como primera línea del constructor de la subclase. La palabra super irá seguida de paréntesis dentro de los cuales pondremos los parámetros que requiera el constructor de la superclase al que queramos invocar. En este caso solo teníamos un constructor de superclase que requería tres parámetros. Si p.ej. hubiéramos tenido otro constructor que no requiriera ningún parámetro podríamos haber usado uno u otro, es decir, super(nombre, apellidos, edad) ó super(), o bien ambos teniendo dos constructores para la superclase y dos constructores para la subclase.

el resultado de esto es:



Para utilizar las librerías del API, existen dos situaciones:


a) Hay librerías o clases que se usan siempre pues constituyen elementos fundamentales del lenguaje Java como la clase String. Esta clase, perteneciente al paquete java.lang,  se puede utilizar directamente en cualquier programa Java ya que se carga automáticamente.


b) Hay librerías o clases que no siempre se usan. Para usarlas dentro de nuestro código hemos de indicar que requerimos su carga mediante una sentencia import incluida en cabecera de clase.


Por ejemplo import java.util.ArrayList; es una sentencia que incluida en cabecera de una clase nos permite usar la clase ArrayList del API de Java. Escribir import java.util.*; nos permitiría cargar todas las clases del paquete java.util. Algunos paquetes tienen decenas o cientos de clases. Por ello nosotros preferiremos en general especificar las clases antes que usar asteriscos ya que evita la carga en memoria de clases que no vamos a usar. Una clase importada se puede usar de la misma manera que si fuera una clase generada por nosotros: podemos crear objetos de esa clase y llamar a métodos para operar sobre esos objetos. Además cada clase tendrá uno o varios constructores.

Encontrar un listado de librerías o clases más usadas es una tarea casi imposible. Cada programador, dependiendo de su actividad, utiliza ciertas librerías que posiblemente no usen otros programadores.

Los programadores más centrados en programación de escritorio usarán clases diferentes a las que usan programadores web o de gestión de bases de datos. Las clases y las librerías básicas deberás ir conociéndolas mediante cursos o textos de formación básica en Java. Las clases y librerías más avanzadas deberás utilizarlas y estudiarlas a medida que te vayan siendo necesarias para el desarrollo de aplicaciones, ya que su estudio completo es prácticamente imposible. Podemos citar clases de uso amplio. En el paquete java.io: clases File, Filewriter, Filereader, etc. En el paquete java.lang: clases System, String, Thread, etc. En el paquete java.security: clases que permiten implementar encriptación y seguridad. En el paquete paquete java.util: clases ArrayList, LinkedList, HashMap, HashSet, TreeSet, Date, Calendar, StringTokenizer, Random, etc. En los paquetes java.awt y javax.swing una biblioteca gráfica: desarrollo de interfaces gráficas de usuario con ventanas, botones, etc.




Podemos hacer un poco mas interesante el ejercicio anterior hagamos  algunos cambios al codigo de Herencia1:

/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package herencia1;

/**
 *
 * @author miguel
 */
import java.util.Scanner; // este es para tomar valores y pasarlos a las variables

public class Herencia1 {

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
    Scanner miScanner = new Scanner(System.in); //instancia que define la forma de aceptar valores
    
    System.out.print("Nombre del profesor :");
    String nombre_p;
    nombre_p = miScanner.nextLine();//la instancia es la misma solo cambia la variable
   
    System.out.print("Apellidos del profesor :");
    String apellidos_p;
    apellidos_p = miScanner.nextLine();
   
    System.out.print("Identificacion :");
    String Id_prof;
    Id_prof = miScanner.nextLine();
   
    System.out.print("Edad del profesor ");
    int edad_p;
    edad_p = miScanner.nextInt();
   
          Profesor profesor1 = new Profesor (nombre_p,apellidos_p,edad_p);
      profesor1.setIdProfesor(Id_prof);
      profesor1.mostrarNombreApellidosYCarnet();
    }
   
}

Puedes determinar que ha cambiado !

Prueba si alteramos la secuencia de captura de datos funcionara correctamente ?

Asignar objetos distintos a la clase Tokenizer, y pasarle diferentes argumentos. La clase StringTokenizer nos ayuda a dividir un string en substrings o tokens, en base a otro string (normalmente un carácter) separador entre ellos denominado delimitador.

Un control área de texto, permite varias líneas de texto, cada línea está separada de la siguiente mediante un carácter nueva línea '\n' que se obtiene pulsando la tecla Enter o Retorno. Mediante una función denominada getText obtenemos todo el texto que contiene dicho control. La clase StringTokenizer nos permite dividir el string obtenido en un número de substrings o tokens igual al número de líneas de texto, basado en que el carácter delimitador es '\n'. tambien se pueden considerar '(espacio)  /r /t /b /f ' , incluso se puede designar otros caracteres.

Para usar la clase StringTokenizer tenemos que poner al principio del archivo del código fuente la siguiente sentencia import.


    import java.util.*;

o bien

    import java.util.StringTokenizer;




Entonces se modificaria para quedar:



El codigo quedaria de la siguiente forma:

package tokens;
/**
 *
 * @author Miguel
 */
import java.util.StringTokenizer;
public class Tokens {
  // para que se ejcute este clase en este programa no olvidemos usar la clase main
    public static void main(String[] args) {
       StringTokenizer st1, st2; //definimos 2 variables
       String cita1 ="TEXTO 6  -3/4";
       st1 = new StringTokenizer(cita1); //instanciamos, el objeto st1
                                         // se le pasa el string cita1 el cual
                                         // esta dentro del parentesis.
       System.out.println("Token 1 : "+st1.nextToken());// toma el primer grupo de caracteres
       System.out.println("Token 2: "+st1.nextToken());//toma el segundo grupo de caracteres
       System.out.println("Token 3: "+st1.nextToken());// toma el tercer grupo de caractres
                                                                                 // estos estan sparador por un espacio
       String cita2 ="DSRG@R 32/ 35@2/17";
       st2 = new StringTokenizer(cita2,"@"); // se instancia el objeto st2, se pasa adicional la @
                                                                  // se agrega como argumento
       System.out.println("Token 1 : "+st2.nextToken());// toma el primer grupo de caracteres
       System.out.println("Token 2: "+st2.nextToken());//toma el segundo grupo de caracteres
       System.out.println("Token 3: "+st2.nextToken());// toma el tercer grupo de caractres
                                                                               // estos estan separador por una arroba @
                                         
   // se puede apreciar la uilidad de los objetos con argumentos, de otra forma seria mas
   // complejo obtener esto
  
    }
   
}

Para el programador es más cómodo usar las funciones miembro equivalentes nextToken y hasMoreTokens. Para extraer el nombre, el primer apellido y el segundo apellido, escribiremos:


String nombre="Miguel Santos Montoya";
    StringTokenizer tokens=new StringTokenizer(nombre);
    while(tokens.hasMoreTokens()){
            System.out.println(tokens.nextToken());

El método hasMoreTokens() se utiliza para comprobar si hay más elementos disponibles de cadena.

Existe otra forma de asignar variables a objetos, puede ser de la siguiente forma:




para demostrar esto vease lo siguiente:



Formemos un nuevo proyecto lo llamaremos Punto, el propósito es demostrar que es posible crear una variable en un objeto, en este ejemplo usamos lo siguiente:

  localizacion.x = 4; // el objeto localizacion se le incluye una variable esn este caso x
  localizacion.y =8;  // // el objeto localizacion se le incluye una variable esn este caso y

observamos que el objeto localizacion tiene una variable  x y la y.

también hay que crear las variables de x y de y como elementos de la clase de forma privada, el significando es que solo tienen ámbito de acción en la clase Punto.

el resultado es :



Modifiquemos algo nuestro programa, a reserva de criticar el programa, volvemos asignar el objeto.variable de la siguiente forma: (agregamos esta lineas al programa)

    localizacion.x = 0;
    localizacion.y = 1;
   System.out.println("Inicializando el segundo punto");
   System.out.println("X es igual a: "+localizacion.x);
   System.out.println("Y es igual a: "+localizacion.y);

se vera de esta forma:



y el resultado es:



el programa completo es el siguiente:

/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package punto;

/**
 *
 * @author celnet_3
 */
public class Punto { // inicia la clase

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) { // inicia main
   Punto localizacion; //tambien se puede instancia de esta manera
                                // se instancia con el nombre de la clase y un objeto (localizacion)
         localizacion = new Punto(); // se crea el objeto localizacion, debe de incluirse
                                                   // la declaracion de variables de tipo private esta en la parte inferior sigue estando dentro de la clase
       
   localizacion.x = 4; // el objeto localizacion se le incluye una variable esn este caso x
   localizacion.y =8;  // el objeto localizacion se le incluye una variable esn este caso y
   System.out.println("Inicializando el punto");
   System.out.println("X es igual a: "+localizacion.x);
   System.out.println("Y es igual a: "+localizacion.y);
  
    localizacion.x = 0;
    localizacion.y = 1;
   System.out.println("Inicializando el segundo punto");
   System.out.println("X es igual a: "+localizacion.x);
   System.out.println("Y es igual a: "+localizacion.y);
   
    }  // termina main
    private int x;
    private int y;
} //termina la clase

(más adelante se vera que hay una clase llamada Point que simplifica la operación de la clase)

En el siguiente ejemplo se utilizará una clase y con un objeto el cual será un string, y este se asignará como parte de una función que manipule el string del objeto







resultado:


Ahota te toca analizar el programa e indica que es lo que observas y obten unas conclusiones de esto, y realiza un programa que incluya clases y objetos (el tema es abierto).

el programa:

/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package revisarstring;

/**
 *
 * @author celnet_3
 */
public class RevisarString {

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
      String str = "la estupidez insiste siempre";
      System.out.println("El string es :"+str);
      System.out.println("El tamaño de este string :"+str.length());
      System.out.println("Caracter en posicion 5 :"+str.charAt(5));
      System.out.println("El substring de 3 a 12 "+str.substring(3,12));
      System.out.println("El index del string z : "+str.indexOf('z'));
      System.out.println("El index del inicio del "+"substring \"siempre\" :"+str.indexOf("siempre") );
      System.out.println("El string en mayusculas "+str.toUpperCase());
    }
   
}

REFERENCIAS A OBJETOS

Una refencia es una dirección que indican en donde están almacenados los métodos, y variables de un objeto.

Las referencias no crean ni forman objetos.



Compila y ejecuta el código

Modifiquemos los valores de los objetos y veamos cómo se afectan las variables por referencia.



Al ejecutar el codigo:



Se observa que los valores por refencia se actualizan ...

En java  no existe el concepto de punteros como en C++,  usa variables de referencia como se aprecia en el codigo anterior.

EL CASTING

Se trata de hacer una conversion de información entre distintos formatos

Hay varios tipos de CASTING:



Con el casting lo que hace no es modificar el origen, lo que hace es crear un nuevo objeto o variable.

El proceso se realiza entre variables numéricas, las variables booleanas no pueden ser usadas para casting, por ejemplo:

float fuente = 13.456f;

int destino =(int) fuente;

Se ve que la variable fuente, es un tipo float, y para realizar el casting a int (entero) usamos un formato especial usando el tipo entre parentesis (int).

algunos tipos no son compatibles entre sí como int y double.

public class PruebaApp {
public static void main(String[] args) {
int a=1;
double b=2.5;
b=a;
System.out.println(b);
}
}

El código anterior, no nos dará ningún error, ya que double si puede contener un int, pero si cambiamos la linea b=a; por a=b; nos informara un error, esto es porque int no puede contener un double, pero si usamos un casting si nos dejara ejecutar.

public class PruebaApp {
 
    public static void main(String[] args) {
 
        int a=1;
 
        double b=2.5;
 
        a=(int)b;
 
        System.out.println(a);
    }
}

Como vemos, un casting se indica entre paréntesis con el tipo de dato al que queremos pasar, en este caso int. La variable a, contendrá un 2 y no un 2.5.

El error relacionado con los castings es Type mismatch: cannot convert from (dato1) to (dato2)
No se puede hacer castings entre todos los tipos, por ejemplo, entre un int y un String.

El error que aparece es este Cannot cast from (dato1) to (dato2).
Vamos a ver otro ejemplo muy común para usar un casting. Si recuerdas dijimos en otro post, que int y char son compatibles, si tenemos un int y hacemos un casting a char este se convertirá en un carácter asociado de la tabla ASCII. Veamos un ejemplo:

public class PruebaApp {
 
    public static void main(String[] args) {
 
        int codigo=97;
 
        char codigoASCII=(char)codigo;
 
        System.out.println(codigoASCII);
    }
}

el codigo de casting es fácil de entender:


Un codigo que explica el casting es el siguiente:



Realiza este ejemplo, y despúes realiza uno por tu cuenta.

Casting Implícito (Widening Casting)

El casting implícito radica en que no se necesita escribir código para que se lleve a cabo. Ocurre cuando se realiza una conversión ancha – widening casting – es decir, cuando se coloca un valor pequeño en un contenedor grande.

      Ejemplo:

                //Define una variable de tipo int  con el valor 100

                int numeroEntero = 100;

                //Define una variable de tipo long a partir de un int

                long numeroLargo = numero;

Casting Explicito (Narrowing Casting)

El casting explicito se produce cando se realiza una conversión estrecha – narrowing casting – es decir, cuando se coloca un valor grande en un contenedor pequeño. Son susceptibles de perdida de datos y deben realizarse a través de código fuente, de forma explicita.

      Ejemplo:

                //Define una variable del tipo int con el valor 250

                int numeroEntero = 250;

                //Define una variable del tipo short y realizr el casting de la variable numero

                short s = (short) numero;

Casting de superclase y subclase.

Reglas:

No se puede hacer casting de una variable primitiva a un objeto:

En Java existen clases para cada variable primitiva.

Class Boolean

Class Byte

Class Character

Class String

Class Double

Class Float

Class Integer

Class Long

Class Short

Todos son objetos por eso comienzan con mayusculas.

como esto:


Integer cantidad = new Integer (1234);

int nuevaCantidad = cantidad.intValue();

Un casting que es muy socorrido es de realizar el casting de string a valor integer:

String cuenta = "25";

int miCuenta = Integer.parseInt(cuenta);

Procedamos con lo siguiente:




El programa completo es:

package casting2;
import java.util.Scanner;
import static javafx.application.Platform.exit; //este es para el caso de tener que terminar
                                                                   // el programa por valor negativo
public class Casting2 {

    public static void main(String[] args) {
       Scanner miScanner = new Scanner(System.in); //instancia que define la forma de aceptar valores
       System.out.print("El numero a calcular la raiz como valor entero :");
       String numeros; //variable primitiva de tipo string
       numeros = miScanner.nextLine();
       int numero; // variable primitiva de tipo int
       numero = Integer.parseInt(numeros); //casting de string a int usando Integer.parseInt()
       
       if (numero <= 0){
              System.out.println("No es posible no se permiten raices negativas ");
              exit(); // vease la linea import static javafx.application.Platform.exit;
       }   
    else{
        System.out.println("La raiz cuadrada de :"+numero+" es "+Math.sqrt(numero)); //puedes ver mas aqui. y este otro
      }  
    }

}

Una clase, método o campo declarado como estático (static) puede ser accedido o invocado sin la necesidad de tener que instanciar un objeto de la clase


AUTOBOXING Y UNBOXING

Es una característica que se encuentra a partir de la versión 1.5 de Java, que permite convertir de objeto (wrapper) a primitivo y viceversa, sin necesidad de hacer un cast explicito.

Int I = 0;
I = new Integer(5); //auto-unboxing
Integer I2 = 5; // autoboxing

El autoboxing realmente no evita el cast de tipos, simplemente lo realiza de forma implícita, por lo tanto debemos evitar en la medida de lo posible estas situaciones.

//Integer - int
Integer objectInt = Integer.valueOf(10);
int primitiveInt = objectInt.intValue();
//o Autoboxing
primitiveInt = objectInt;
 
//Boolean - boolean
Boolean objectBool = true;
boolean primitiveBool = objectBool.booleanValue();
//o Autoboxing
primitiveBool = objectBool;

De forma practica es:

Float total = new Float(1.3);
float sum = total / 5;

TERMINA EL CAPITULO 3

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://www.arquitecturajava.com/java-constructores-y-super/
https://www.aprenderaprogramar.com/index.php?option=com_content&view=category&id=68&Itemid=188
https://users.dcc.uchile.cl/~lmateu/Java/Apuntes/tiposprim.htm
https://sekthdroid.wordpress.com/2012/10/02/declaracion-de-variables-en-java/
https://www.programarya.com/Cursos/Java/Sistema-De-Tipos/Variables-Y-Tipos
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
http://www.sc.ehu.es/sbweb/fisica/cursoJava/fundamentos/fundamentos.htm
https://www.adictosaltrabajo.com/tutoriales/la-directiva-static-en-java/