domingo, 26 de julio de 2009

SCJP Declaraciones Inicializacion y Alcance 2

Declarando una interface
Cuando creamos una interface, lo que estamos realizando es un contrato de lo que la clase que implementa dicha interface tiene que hacer sin decir nada acerca de como la clase lo hará, en pocas palabras la interface indica que se va a hacer y la clase que implementa dicha interface indica como se va implementar, de esto concluimos que una interface es un contrato que la clase que lo implementa debe de cumplir. Por ejemplo si tenemos la interface Imprimible definida de la siguiente manera:

public interface Imprimible{
public void imprimirAPdf();
public void imprimirAExcel();
}

Y una clase Libro que implementa la interface anterior de la siguiente manera:

public class Libro implements Imprimible{
public void imprimirAPdf(){
-- Aqui va el código que imprime el libro en formato pdf
}
public void imprimirAExcel(){
-- Aqui va el código que imprime el libro en formato excel
}
}

La clase al implementar la interface debe de cumplir con el contrato, es decir debe de proveer una forma de implementación para cada uno de los métodos de la interface, en el ejemplo vemos que la clase implementa los métodos declarando código entre las llaves de apertura y cerradura de dichos métodos, en la interface después de los parentesis termina su declaración con un punto y coma.

Podemos pensar en las interfaces como clases 100% abstractas, asi como una clase abstracta una interface define métodos abstractos que toman la siguiente forma:

abstract void nombreMetodo();

Pero mientras que una clase abstracta puede definir tanto métodos abstractos como no abstractos, una interface solo puede tener métodos abstractos, es decir podemos tener una clase abstracta de la siguiente manera:

public abstract class Libro{
-- Método abstracto:
public abstract void calcularCosto();

-- Método no abstracto:
public void calcularVentas(){
--Aquí la implementación del método.
}
}

Pero no podemos hacer una interface parcialmente abstracta, las interfaces son 100% abstractas, es decir todos sus métodos son abstractos(no tienen una implementación { ... } ), por lo que la siguiente interface es incorrecta:

public interface Imprimible{
-- Método abstracto:
public abstract void imprimirAPdf();

-- Método no abstracto:
public void imprimirAExcel(){
--Aquí la implementación del método.
}
}

Algunas reglas más sobre la declaración de las interfaces son las siguientes:

1. Todos los métodos de las interfaces son implicitamente públicos y abstractos, en otras palabras no necesitamos escribir los modificadores public y abstract en la declaración del método, el método siempre será públic y abstracto. Veamos, si tenemos la siguiente interface:

public interface Imprimible{
void imprimirAPdf();
int imprimirAExcel();
}

Entonces lo que el compilador realmente analizará es:

public interface Imprimible{
public abstract void imprimirAPdf();
public abstract int imprimirAExcel();
}

2. Todas las variables definidas en una interface deben ser públicas estáticas y finales, en otras palabras las interfaces pueden declarar solo constantes, no variables de instancia.

--Recordar una variable de instancia;
public class Libro{
-- variable de instancia:
private int ancho;
}

3. Los métodos de las interfaces no deben ser estáticos. No podemos hacer lo siguiente:
public interface Imprimible{
public static void imprimir();
}

4. Como los métodos de las interfaces son abstractos entonces no podemos definirlos tambien como finales final, strictfp ó native.

5. Una interface puede extender una o más interfaces, es decir podemos hacer lo siguiente:

public interface interface1{
void metodo1();
}

public interface interface2{
void metodo2();
}

public interface interface3 extends interface1,interface2{
void metodo1();
void metodo2();
void metodo3();
}

6. Una interface solo puede extender interfaces no puede extender clases, por ejemplo si tenemos la clase:

public class Descargable{
protected int descargar(){
-- XXX
}
}

entonces la siguiente declaración de interface es incorrecta:

public interface interface3 extends Descargable{
protected int descargar();
}

7. Una interface no puede implementar otra interface o una clase, no podemos hacer lo siguiente:

public interface interface3 implements interface1,interface2{
void metodo1();
void metodo2();
void metodo3();
}

8. Una interface debe ser declarada con la palabra clave interface.

Declarando constantes en interfaces
Nosotros podemos declarar constantes en una interface, haciendolo garantizamos que cualquier clase que implementa la interface tendrá acceso a la misma constante, la regla principal para las constantes es la siguiente:

public static final = ;

Por ejemplo si tenemos la siguiente interface:

public interface Imprimible{
int ancho = 100;
int largo = 170;
public void imprimir( );
}

y la siguiente clase:

public class Libro implements Imprimible{
public void imprimir(){
--Nosotros podemos usar las constantes
System.out.println(ancho*largo):

--Pero no podemos asignarles un valor porque las declaraciones int ancho = 100;
--el compilador lo analiza como public static final int ancho = 100; es decir es
--declarado como final y estático ya no podemos modificarlo, por lo tanto es incorrecto:
ancho = 666;
}
}

SCJP Declaraciones Inicializacion y Alcance 1

Cuando escribimos código en java, lo que estamos escribiendo es justamente clases o interfaces, dentro de estas clases como conocemos pueden haber variables y métodos(y algunas otras cosas más), la forma en la que declaramos las clases, métodos y variables afecta en forma sustancial el comportamiento del código, por ejemplo un método público puede ser accedido desde código ejecutandose en cualquier lugar en tu aplicación, haciendo el método privado lo oculta a cualquier posible llamada(excepto a la clase en la cuál fué declarada).

Reglas de declaración de archivos fuente
  1. Solo puede haber una clase pública por archivo fuente.
  2. Los comentarios pueden aparecer al inicio o al fin de cualquier línea en el archivo de código fuente.
  3. Si es que hay una clase pública el nombre del archivo debe de coincidir con el nombre de la clase, por ejemplo si hay una clase declarada public Casa entonces el nombre del archivo deberá ser Casa.java
  4. Si la clase es parte de un paquete, la declaración del paquete debe ser la primera línea en el archivo de código fuente, antes de cualquier declaración de importacion import que pueda estar presente.
  5. Si hay declaraciones de importacion import, estas declaraciones deben de ir entre la declaración del paquete(si es que lo hubiera) y la declaración de la clase.
  6. Declaraciones de importación import y de paquetes package aplican a todas las clases dentro de un archivo de código fuente, en otras palabras, no hay manera para declarar multiples clases en un archivo y tenerlos en diferentes paquetes o usar diferentes importaciones.
  7. Un archivo puede tener más de una clase no pública.
  8. Archivos con clases no públicas pueden tener un nombre que no coincide con cualquiera de las clases en el archivo.
Declaraciones de clases y modificadores
  1. Modificadores de acceso: public, protected, private
  2. Modificadores de no-acceso: strictfp, final y abstract
Acceso de Clase
Que es lo que significa acceder a una clase?, cuando decimos que el código de una clase(class X) a accedido a otra clase(class Y) esto significa que la clase X puede hacer cualquiera de las 3 siguientes acciones:

Crear una instancia de la clase Y.
class X{
Y y = new Y( );
}

Extender la clase Y.
class X extends Y{ }

Accesar ciertos métodos y variables de la clase Y, dependiendo del control de acceso de estos métodos y variables.
class X{
Y y = new Y( );
X(){
y.holamundo();
}
}

Modificador de Acceso por Defecto.
Una clase con default access no tiene un modificador de acceso que le precede en su declaración, es decir tiene la forma class X{ } y no public class X { } este es el control de acceso que se obtiene cuando no escribimos el modificador en la declaración, las clases con default access pueden ser vistas como clases con nivel de acceso a nivel de paquete, porque una clase con default access puede ser vista solo por clases dentro del mismo paquete. Por ejemplo si tenemos una clase llamada Persona en el paquete miempresa.core declarada de la siguiente manera:

package miempresa.core;
class Persona{ }

y queremos usar la clase anterior pero en otro paquete digamos miempresa.rrhh con la clase Empleado extendiendola de la siguiente manera:

package miempresa.rrhh;
class Empleado extends Persona{ }

Al compilar la clase Persona no hay problema, pero cuando queremos compilar la clase Empleado entonces el compilador nos retorna un error diciendonos que no tiene acceso a la clase Persona esto es cierto porque el modificador de acceso de la clase Persona es por default, es decir no está indicado explicitamente(no está escrito) y por lo tanto solo puede ser visto por aquellas clases declaradas en el mismo paquete, es decir en el paquete miempresa.core, lo anterior se puede solucionar declarando la clase Empleado en el paquete miempresa.core ó declarando el modificador de acceso a public

Modificador de Acceso Público.
Una declaración de clase con la palabra clave public da a todas las clases de todos los paquetes acceso a esta clase pública, es decir en el ejemplo anterior si a la clase Persona la redeclaro como
public class Persona{ } entonces esta clase puede ser accedida desde cualquier clase en cualquier paquete desde mi aplicación. Ojo que si tratamos de usar la clase pública desde otro paquete entonces debemos de importar dicha clase con la palabra clave import

Otros Modificadores de Clase que no son de Acceso.
Podemos modificar la declaración de una clase con las palabras clave final y abstract

Clases Finales.
Cuando es usada en la declaración de una clase, la palabra clave final significa que la clase no puede ser extendida, en otras palabras ninguna clase puede heredar o extender una clase declarada final si intentamos hacerlo en compilador nos retornará un error.

Clases Abstractas.
Una clase abstracta no puede nunca ser instanciada, su único proposito es ser extendida.
Es decir si tenemos:
public abstract class Persona{ }
no podemos hacer esto:
Persona p = new Persona();
lo que debemos de hacer es lo siguiente:
public class Empleado extends Persona{ }

sábado, 25 de julio de 2009

Arquitectura de una Base de Datos Oracle

Un servidor Oracle consiste de una "instancia Oracle" (memoria=SGA+PGA) y de una "base de datos Oracle" (disco=datafiles) esta base de datos en ejecución está asociada con una instancia.

Es así que cuando una base de datos es iniciada sobre un servidor de base de datos, el software de oracle asigna un área de memoria compartida llamada "System Global Area (SGA)" ó "Area Global del Sistema" e inicia varios procesos en background de Oracle, esta combinación del SGA y los procesos Oracle conforma la instancia.

Después de iniciar una instancia, el software de Oracle asocia la instancia con una base de datos específica, dicho proceso es llamado el proceso de montar(STARTUP MOUNT) la base de datos, ahora la base de datos está entonces lista para ser abierta(STARTUP OPEN), lo cual la hace accesible a usuarios autorizados.

Multiples instancias pueden ejecutarse concurrentemente sobre la misma computadora, cada una accesando su propia base de datos física. La arquitectura de la base de datos se puede entonces observar como varios componentes estructurales interrelacionados.

Una base de datos Oracle usa estructuras de memoria y procesos para gestionar y accesar la base de datos, todas estas estructuras de memoria existen en la memoria principal(RAM) del servidor(HW) que constituye el servidor de base de datos.

Los procesos son hilos que trabajan en la memoria de estos servidores(HW), asi un proceso es definido como un hilo de control o un mecanismo en un sistema operativo que puede ejecutar una serie de tareas.

Las estructuras de memoria básicas asociadas con una instancia Oracle incluyen:

System Global Area (SGA): Memoria compartida por todos los procesos.

Program Global Area (PGA): Memoria privada a cada proceso de servicio y de fondo, solo hay una PGA por cada proceso.

El SGA es un área de memoria que contiene datos e información de control para la instancia, incluye las siguientes estructuras de datos:

Database buffer cache: Memoria cache(de rápido acceso) de los bloques de datos recibidos desde la base de datos, es decir cuando queremos obtener un dato y este no está en memoria entonces es primero obtenida del disco y copiada a este buffer para una posterior obtención más rápida, es decir el próximo proceso ya no se vaya a disco sino al buffer.

Redo log buffer: Memoria cache(de rápido acceso) de la información "redo" hasta que pueda ser escrita a los archivos físicos "redo logs" que se encuentran en disco. Cada transacción que realizamos es primero copiada a este buffer y después a los archivos "redo logs" en disco.

Shared pool: Memoria cache(de rápido acceso) que almacena varias estructuras que pueden ser compartidas entre procesos de usuario.

Large pool: Es un área opcional que proporciona grandes asignaciones de memoria para ciertos procesos largos, como son operaciones de backups y de recuperación así como tambien procesos de entrada y salida al disco.

Java pool: Es usado para todas las sesiones específicas a código java y datos dentro de la máquina virtual java.

Streams pool: Es usado por Oracle Streams.

Cuando iniciamos una instancia la cantidad de memoria asignada para el SGA es mostrada en la interface de comandos de sqlplus o en Enterprise Manager, esta información es mostrada en bytes.