Java: Definición de clases II.

 • Métodos estáticos: 


-Aquel que se puede usar sin una llamada de objeto.

-Pertenecen a la clase y sus definiciones se dan dentro de la definición de la clase.


public static type myMethod(parámetros)

{

...

}


 • Variables estáticas:


-Pertenecen a la clase como entero, y no sólo a un objeto.

-Sólo hay una copia de una variable estática por clase, a diferencia de las variables de instancia donde cada objeto tiene su propia copia.

-Todos los objetos de la clase pueden leer y cambiar una variable estática.

-Un método no puede acceder a una variable de instancia pero sí a una variable estática. 


private static int myStaticVariable;


-Las variables estáticas siempre deben definirse como privadas a menos que sea una constante definida.

-Las variables estáticas pueden declararse e inicializarse en el mismo tiempo.


private static int myStaticVariable = 0; 


-Las variables estáticas booleanas se inicializan a falso.

-Otras variables estáticas de tipos primitivos se inicializan al cero de su tipo.

-Las variables estáticas de tipo de clase se inicializan a nulas.

-Declaración de un objeto definido constante: 


public static final int BIRTH_YEAR = 1954; 


Al ser constante está bien definirla como pública. 


-Cuando se hace referencia a esa constante definida fuera de su clase se usa el nombre de su clase en lugar de un objeto que llama.


int year = MyClass.BIRTH_YEAR;


 • La clase Math:


-Proporciona una cantidad de estándares métodos matemáticos.

-NO requiere importación.

-Todos sus métodos y datos son estáticos, se invocan con el nombre de clase Math en lugar de un objeto de llamada.

-La clase Math tiene dos constantes predefinidas, E (e, la base)


area = Math.PI*radius*radius


-Métodos: 


public static double pow(double base, double exponent)

Math.pow(2.0, 3.0) ---> 8.0

-Multiplica la base por el exponente.


public static double abs(double argument)

Math.abs(-6) 

Math.abs(6)

Math.abs(-5.5)

Math.abs(5.5)

-Devuelve el valor absoluto de "argument".


public static double min(double n1, double n2)

Math.min(3,2) ---> 2 

-Devuelve el valor mínimo entre ambos datos.


public static long round(double argument)

public static int round(float argument)

Math.round(3.2); ---> 3

Math.round(3.6); ---> 4

-Redondea.


public static double ceil(double argument)

Math.ceil(3.2) 

Math.ceil(3.9) 

Ambos: 4.0

-Devuelve el número entero más pequeño mayor o igual que el argumento.


public static double floor(double argument)

Math.floor(3.2)

Math.floor(3.9) 

Ambos: 3.0

-Devuelve el número entero más grande menor o igual que el argumento.


public static double sqrt(double argument)

Math.sqrt(4) ---> 2.0 

-Devuelve la raíz cuadrada. 


 • Clases de envoltura:

-Las clases de envoltura proporcionan un tipo de clase correspondiente a cada uno de los tipos primitivos.

-Las clases de contenedor para el byte de tipos primitivos shor, long, float, double y char son (en orden) byte, short, long, float, double y character.

-Las clases de envoltura también contienen una cantidad de útiles constantes predefinidas y métodos estáticos.


-Boxing: El proceso de pasar un valor de tipo primitivo a un objeto de su clase contenedora.


-Para convertir un valor primitivo en una clase "equivalente" escriba value, crear un objeto de clase correspondiente contenedora que usa el valor primitivo como argumento.

-El nuevo objeto contendrá una variable de instancia que almacena una copia del valor primitivo.

-A diferencia de la mayoría de otras clases, una clase contenedora no tiene un constructor sin argumentos.


Integer integer Object = new Integer(42); 


-Unboxing: El proceso de pasar de un objeto de una clase contenedora al valor correspondiente de un tipo primitivo.


-Los métodos para convertir un objeto de clases contenedoras byte, short, int, long, float, double y character a su tipo primitivo correspondiente son (en orden):


-byteValue

-shortValue

-intValue

-longValue

-floatValue

-longValue

-floatValue

-doubleValue

-charValue


-Ninguno de estos métodos toma un argumento.


int i = integerObject.intValue();


-Boxing y Unboxing automático:


-En lugar de crear un objeto de la clase contenedora utilizando la nueva operación se puede hacer como un lanzamiento de tipo automático:


Integer integerObject = 42;


-En lugar de tener que invocar el método apropiado (introValue, doubleValue, charValue, etc) para convertir de un objeto de una clase contenedora a un valor de tipo primitivo asociado, el valor primitivo puede ser recuperado automáticamente. 


int i = integerObject;


-Constantes y métodos estáticos en clases de envoltura:


-Las clases de envoltura incluyen constantes útiles que proporcionan los valores más grandes y más pequeños para cualquiera de los tipos de números primitivos.


-Ejemplos: 

Integer.MAX_VALUE, Integer.MIN_VALUE, Double.MAX_VALUE, Double.MIN_VALUE, etc.


-La clase booleana tiene nombres para dos constantes de tipo booleano.


-Boolean.TRUE y Boolean.FALSE son los objetos booleanos que corresponden a los valores verdadero y falso del tipo primitivo booleano.


-Las clases de envoltura tienen métodos estáticos que convierten una representación de cadena de valor.


-Ejemplos: 

Double.toString(123.99); devuelve el valor de cadena "123.99".


 • Métodos de la clase Character:


public static char toUpperCase(char argument) 

character.toUpperCase('a') ---> A

-Devuelve el carácter en mayúscula.


public static char tolowerCase(char argument) 

character.toLowerCase('A') ---> a

-Devuelve el carácter en minúscula.


public static boolean isUpperCase(char argument) 

character.isUpperCase('A') ---> True 

character.isUpperCase('a') ---> False

-Devuelve verdadero si la letra es mayúscula.

-Con isLowerCase haría lo contrario.


public static boolean isWhiteSpace(char argument)

character.isWhiteSpace( ' ') ---> True

character.isWhiteSpace('A') ---> False

-Devuelve verdadero si hay un espacio en blanco.


public static boolean isLetter(char argument)

character.isLetter('A') ---> True

character.isLetter('%') ---> False

-Devuelve verdadero si el argumento se trata de un carácter.


public static boolean isDigit(char argument)

character.isDigit('5') ---> True

character.isDigit('A') ---> False

-Comprueba si es un dígito, si no lo es devuelve falso.


public static boolean isLetterOrDigit(char argument)

character.isLetterOrDigit('A') ---> True

character.isLetterOrDigit('&') ---> False

-Comprueba si el argumento es una letra o un dígito. 


• Variables y memoria:


-Cada variable se implementa como una ubicación de la memoria del ordenador.

-Cuando la variable es un tipo primitivo, el valor de la variable se almacena en la ubicación de la memoria.

-Cuando la variable es un tipo de clase, sólo la dirección de memoria donde se encuentra su objeto se almacena en la ubicación de la memoria.


• Parámetros de clase:


-Un parámetro de clase es una variable local que se establece igual al valor del argumento.

-Cualquier cambio en el valor del parámetro no puede cambiar el valor de su argumento.

-El valor conectado a un parámetro de tipo de clase es una dirección de memoria.

-Cualquier cambio en el objeto nombrado por el parámetro se harán al objeto llamado por el argumento porque son el mismo objeto. 

-Cualquier cambio realizado en el parámetro de tipo clase en sí (su dirección) no cambiará su argumento (dirección de memoria.)


• Diferencias entre clases de tipo primitivo y parámetros:


-Un método no puede cambiar el valor de una variable.

-Un método puede cambiar valores de instancia de un tipo de clase que es un argumento para el método.


public class ParametersDemo {


   public static void main(String[] args) {


        ToyClass2 object1 = new ToyClass2();

        ToyClass2 object2 = new ToyClass2(); 


        object1.set("Scorpius", 1);

        object2.set("John Crichton", 2);


       System.out.println(object2); ---> John Crichton 2

       object1.makeEqual(object2); --->  Scorpius 1


       Un argumento de tipo clase puede cambiar


        int aNumber = 42;

        System.out.println("Value " + aNumber); ---> 42

        object1.tryToMakeEqual(aNumber);

        System.out.println("Value " + aNumber); ---> 42 


      }


}


Un argumento de tipo primitivo no puede cambiar.


• ERROR: Uso de = y == con variables de tipo de clase:


-Usado con variables de tipo de clase, el operador = produce dos variables que nombran al mismo objeto.

-La prueba de igualdad == también se comporta de manera diferente con variables de tipo de clase.

-El operador == sólo verifica que haya dos variables de tipo de clase en la misma dirección de memoria.

-A diferencia de =, no significa que su variable de instancia tenga los mismos valores.

-Dos objetos en dos ubicaciones diferentes cuyas variables de instancia tienen exactamente el mismo valor, todavía se probaría como "no igual."


• La constante null:


-Null es una constante especial que se puede asignar a una variable de cualquier tipo de clase.


YourClass yourObject = null;


-Se usa para indicar que la variable no tiene "valor real". 

-A menudo se usa en constructores para inicializar las variables de instancia de tipo de clase cuando no hay un objeto obvio para usar.

-Null no es un objeto, es una especie de "marcador de posición" para una referencia que no nombre ninguna ubicación de memoria.

-Debido a que es como una dirección de memoria, se usa ?? o ! (en lugar de igual) para probar si una variable de clase contiene nulo.


if(yourObject == null)


ERROR: Puntero nulo:


-Aunque una variable de clase se puede inicializar a nulo, esto no quiere decir que null sea un objeto.

-Null es sólo un marcador de posición para un objeto.

-Un método no puede ser invocado usando una variable que es inicializada a nulo.

-El objeto que llama y que debe invocar un método no existe.


El nuevo operador y objetos anónimos:


-El nuevo operador invoca un constructor que inicializa un objeto y devuelve una referencia a la ubicación en memoria del objeto creado.

-Esta referencia se puede asignar a una variable de clase de tipo objeto.

-A veces, el objeto creado se usa como argumento para un método, y nunca es usado más.

-En este caso, el objeto no necesita asignarse a una variable, dado un nombre.

-Un objeto cuya referencia no está asignada a una variable es llamado objeto anónimo.


String string1 = null;

String string 2 = null;


double number1 = Double.parseDouble(string1);

double number2 = Double.parseDouble(string 2);


Uso y uso indebido:


-Al escribir un programa es muy importante asegurar que las variables de instancia privadas permanezcan verdaderamente privadas.

-Para una variable de instancia de tipo primitivo, sólo agregando el modificador privado a su declaración debe asegurar que no habrá filtraciones de privacidad.

-Para una variable de instancia de tipo de clase agregar el modificador privado solo no es suficiente.


Designando una clase persona: variables de instancia:


-Una clase persona simple podría contener variables de nstancia representando el nombre de una persona, la fecha en que nacieron y la fecha en que murieron.

-Estas variables de instancia serían todos tipos de clases: nombre de tipo cadena y dos de tipo fecha.

-Como primera línea de defensa para la privacidad, cada una de las variables de instancia serían declaradas privadas.


Public class Person {


private String name;

private Date born;

private Date died;


Designando una clase persona: constructor:


-Para existir una persona debe tener al menos un nombre y una fecha de nacimiento.

-Por lo tanto, no tendría sentido no tener argumento constructor de clase persona.

-Una persona que todavía está viva no tiene fecha de muerte, por lo que el constructor de la clase Persona deberá ser capaz de tratar con un valor nulo para la fecha de la muerte.

-Cuando se proporcionan ambas fechas deberán ser revisadas por consistencia.


public Person (String initialName, Date birthDate, Date deathDate)

{

if(consistent(birthDate, deathDate)) 

{

name = initialName;

born = new Date(birthDate);


if(deathDate == null) {

died = null;

}

else 

{

died = new Date(deathDate);

}

else 

{

System.out.println("Inconsistent dates");

System.out.println(0);

}

}


Designando una clase persona: la clase invariante:


-Una declaración que siempre es verdadera para cada objeto de clase se llama invariante de clase.

-Un invariante de clase puede ayudar a definir una clase de forma consistente y forma organizada.

-Para la clase persona, lo siguiente debe ser cierto: Un objeto de la clase persona tiene una fecha de nacimiento (que no es nulo), y si el objeto tiene una fecha de fallecimiento, entonces la fecha de la muerte es igual o posterior a la fecha de nacimiento.

-Verificar la clase persona confirma que esto es cierto de cada objeto creado por un constructor y todos los demás métodos preservan la verdad de esta declaración.


/** Clase invariante: Una persona tiene siempre una fecha de nacimiento y si la persona tiene una fecha de muerte entonces la fecha de muerte es igual o después de la fecha de nacimiento.


Para ser consistente, birthDate no debe ser nula. Si no hay una fecha de muerte (deathDate = null), que es consistente con el birthDate. De lo contrario, la fecha de nacimiento debe ser anterior o igual a la fecha de muerte.

private static boolean consistent(Date birthDate, Date deathDate) {


if(birthday == null) {

return false;

}

else if(deathDate == null) {

return true;

}

else {

return(birthDate.precedes(deathDate || birthDate.equals(deathDate))

}

}


Designando una clase persona: los métodos equals y datesMatch:


-La definición de equals para la clase persona incluye una invocación de equals para la clase String y una invocación del método es igual para la clase Date.

-Java determina qué método equivale a ser invocado desde el tipo de su objeto de llamada.

-También tenga en cuenta que las variables de instancia muertas son comparadas usando el método datesMatch en lugar del método equals, ya que sus valores pueden ser nulos.


public boolean equals(Person otherPerson) {

if(otherPerson == null) {

return false;

}

else {

return(name.equals(otherPerson.name) && born.equals(otherPerson.born) && datesMatch(died, otherPerson.died)); 

}

}


--> Para coincidir fecha1 y fecha2 debe ser la misma fecha o ambas deben ser nulas.


private static boolean datesMatch(Date date1, Date date2)

{

if(date1 == null) {

return(date2 == null);

} else if(date2 == null) {

return false;

}

else {

return(date1.equals(date2));

     }

}


Designando una clase persona: el método String:


-Al igual que el método de igualdad, hay que tener en cuenta que la clase persona del método toString incluye invocaciones de la clase fecha del método toString.


public String toString() {

String diedString;


if(died == null) {

diedString = ""; // Empty String

}

else { 

diedString = died.toString();

return(name * "," + born + "-" + diedString); 

    }

}


Constructores de copia:


-Un constructor de copia es un constructor con un solo argumento del mismo tipo que la clase.

-El constructor de copia debe crear un objeto que es un objeto separado e independiente, pero con las variables de instancia establecidas para que sea una copia exacta del objeto argumento.

-Observe cómo, en el constructor de copia de fecha, los valores de todo el tipo primitivo privado las variables de instancia simplemente se copian.


Constructor copy para una clase con variables de instancia de tipo primitivo:


publicDate(Date aDate) {

if(aDate == null) {

System.out.println("Fatal error");

System.exit(0);

}


month = a.Date.month;

day = aDate.day;

year = aDate.year;

}


Constructor copy para una clase con variables de instancia de clase type:


-A diferencia de la clase Date, la clase Person contiene tres variables de instancia de tipo clase.

-Si la instancia de clase de las variables born y died para el nuevo objeto Person fueron meramente copiados, entonces simplemente cambiarían el nombre el nombre de las variables born y died del objeto original de la clase persona.


born = original.born // dangerous

died = original.died // dangerous


-Esto no crearía una copia independiente del objeto original.

-El constructor de copia real para la clase Person es una versión "segura" que crea completamente nuevo y copias independientes de born y died, y por lo tanto, una copia completamente nueva e independiente del objeto persona original.


-Ejemplo:


born = new Date(original.born);


-Hay que tener en cuenta que para definir un constructor de copia correcto para una clase que tiene variables de instancia de tipo de clase, copia los constructores que ya deben estar definidos para las variables de clases de instancia.


public Person(Person original)

{

if(original == null)

{

System.out.println("Fatal error.");

System.exit(0);

}

name = original.name;

born = new Date(original.born);


if(original.died == null) 

died = null;

else

died = new Date(original.died);

}


-La clase String no contiene métodos mutadores que puedan cambiar cualquiera de los datos en una cadena de objeto.

-Una clase que no contiene ningún método (aparte de constructores) que cambian cualquiera de los datos en un objeto de la clase se llama una clase inmutable.

-Los objetos de dicha clase se llaman objetos inmutables.

-Es perfectamente seguro devolver una referencia a un objeto inmutable porque el objeto no puede ser cambiado de alguna manera.

-La clase String es una clase inmutable.

-Una clase que contiene métodos públicos de mutadores u otros métodos públicos que pueden cambiar los datos en sus objetos se llaman una clase mutable y sus objetos se llaman objetos mutables.

-Nunca escriba en un método que devuelva un objeto mutable.

-En su lugar, use un constructor de copia para devolver una referencia a una copia completamente independiente del objeto mutable.


Copia profunda VS copia superficial:


-Una copia profunda de ub objeto es una copia que, con una excepción, no tiene referencias en común con el original.

-Excepción: las referencias a objetos inmutables pueden ser compartidas.

-Cualquier copia que no sea una copia profunda se llama copia superficial.

-Este tipo de copia puede causar peligrosas filtraciones de privacidad en un programa.


Peligro: Filtraciones de privacidad:


-Los ejemplos previamente ilustrados de la clase persona muestra cómo una definición incorrecta de un constructor puede resultar en una fuga de privacidad.

-Un problema similar puede ocurrir con una definición incorrecta con métodos mutadores o de acceso.


-Ejemplo:


public Date getBirthDate() 

{

return born;

}


-En lugar de:


public Date getBirthDate() 

{

return new Date(born);

}


Clases mutables e inmutables:


-El método de acceso getName de la clase persona parece contradecir las reglas para evitar la privacidad de fugas.


public String getName() 

{

return name;

}


Nombres de choque: 


-Los paquetes proporcionan una manera de lidiar con los conflictos de nombres: una situación en que dos clases tienen el mismo nombre.

-Los diferentes programadores que escriben diferentes paquetes paquetes pueden usar el mismo nombre para una o más de sus clases.

-Esta ambigüedad se puede resolver usando el nombre completo para distinguir entre cada clase.

package_name.ClassName

-Si se utiliza el nombre completo, ya no es necesario importar la clase (porque ya incluye el nombre del paquete.)


Introducción a Javadoc:


-Java coloca el interfaz y la implementación de una clase en el mismo archivo.

-Java tiene un programa llamado javadoc que extrae automáticamente la interfaz de una definición de clase y produce documentacion.

-Se presenta en HTML y puede ser visto con un navegador web.

-Si una clase se comenta correctamente, un programador solo necesita consultar esta documentación API (interfaz de programación de aplicaciones) para usar la clase.

-Javadoc puede obtener documentación para cualquier cosa desde una única clase a un paquete completo.


El paquete predeterminado:


-Todas las clases en el directorio actual pertenecen a un paquete sin nombre llamado paquete predeterminado.

-Siempre que el directorio actual (.) sea parte de las variables CLASSPATH, todas las clases en el paquete predeterminado está automáticamente disponible para un programa.


Peligro: no incluye el directorio corriente en su ruta de clase:


-Si se establece la variable CLASSPATH, la corriente del directorio debe ser incluido como una de las alternativas.

-De lo contrario, es posible que Java ni siquiera sea capaz de encontrar los archivos .class para el mismo programa.

-Si la variable CLASSPATH no está configurada, entonces todos los archivos de clase para un programa deben ser puestos en el directorio actual.


Especificando una ruta de clase se compile:


-La ruta de clase se puede especificar manualmente cuando la clase es compilada.

-Simplemente agregue -classpath seguido por el deseado camino de clase.

-Esto compilará la clase, anulando cualquier configuración anterior a CLASSPATH.

-Deberías usar la opción -classpath nuevamente cuando se ejecute la clase.


Paquetes y declaraciones de importación:


-Java usa paquetes para formar bibliotecas de clases.

-Un paquete es un grupo de clases que han sido colocadas en un directorio o carpeta y eso puede ser utilizado en cualquier programa que incluya una declaración de importación que nombra el paquete.

-La declaración de importacion debe estar ubicada al principio del archivo de programa: sólo líneas en blanco, comentarios y declaraciones de paquete pueden precederlo.

-El programa puede estar en un directorio diferente del paquete.


Declaraciones de importación:

-import java util.*; --> Todas las clases en un paquete disponible.


Declaración de paquete:

-package package_name; 


El paquete java.lang:

-El paquete java.lang contiene las clases que son fundamentales para la programación de Java.

-Se importa automáticamente.

-Las clases disponibles por java.lang incluyen Math, String y las clases de envoltura.


Paquete y nombre de directorios:


-Un nombre de paquetes es el nombre de ruta para el directorio o subdirectorios que contienen las clases de paquete.

-Java necesita dos cosas para encontrar el directorio de un paquete: el nombre del paquete 

-La variable de entorno CLASSPATH es similar a la variable PATH, y se configura de la misma manera para un sistema operativo.

-La variables CLASSPATH se establece igual a la lista de directorios (incluido el directorio, "!") en el que Java buscará paquetes en una computadora en particular.

-Java busca y usa el primer directorio en la lista en la que se encuentra el paquete.


Peligro: los subdirectorios no son importados automáticamente:


-Cuando un paquete se almacena en un subdirectorio del directorio que contiene otro paquete, la importación del paquete adjunto no importa el paquete del subdirectorio.

-Declaración de importación.

import utilities.numericstuff*;

Importa sólo el paquete: utilitis numericstuff


-Las declaraciones de importación:


import utilities.numeric.stuff.*;

import utilities.numericstuff.statistical.*;

Importa ambos paquetes: utilities.numericstuff y utilities numericstuff.statistical 


Comentando clases para Javadoc:


-El programa javadoc extrae los títulos de las clases, encabezados para algunos comentarios y encabezados para todos los métodos públicos, variables de instancia y variables estáticas.

-En el modo normal predeterminado no hay cuerpos de métodos de elementos privados extraídos.


-Para extraer un comentario:

*/... */


@TAGS (Etiquetas)


-@Las etiquetas deben colocarse en el orden que se encuentra a continuación.

-Si hay múltiples parámetros, cada uno debe tener su propio @paramen una línea separada, y cada uno debe aparecer de acuerdo con su torsión izquierda de orden en la lista de parámetros.

-Si hay variables autores, cada uno debe tener su propio @author en una línea separada.


Arrancando Javadoc:


-Para ejecutar Javadoc en un paquete, brinde el siguiente:

javadoc -d Documentation_DirectoryPackage_Name

-Los documentos HTML producidos se colocarán en Documentation_Directory.

-Si se omiten el -d y el Documentation_Directory, javadoc creará directorios adecuados para la documentación.

-Para ejecutar javadoc en una sola clase, brindamos el siguiente comando desde el directorio que contiene el archivo de clase:

javadoc ClassName.java

-Para ejecutar javadoc en todas las clases en un directorio, entregue el comando:

javadoc*.java


Opciones para javadoc:


-link Link_To_Other_Docs

-d Documentation_Directory

-author

-version

-classpath List_of_Directories

-private



Comentarios

Entradas populares de este blog

Autenticación y autorización en: Blazor.

¿Qué es Blazor?

¿Qué es Radzen?