Java (Català)

Encara que sembli una obvietat, la base de la Programació Orientada a Objectes és l’objecte. A la vida real tots els objectes tenen una sèrie de característiques i un comportament. Per exemple, una porta té color, forma, dimensions, material … (gaudeix d’una sèrie de característiques) i pot obrir-se, tancar-… (posseeix un comportament). En Programació Orientada a Objectes, un objecte és una combinació d’unes dades específics i de les rutines que poden operar amb aquestes dades. De manera que els dos tipus de components d’un objecte són:

  • Camps o atributs: components d’un objecte que emmagatzemen dades. També se’ls denomina variables membre. Aquestes dades poden ser de tipus primitiu (boolean, int, double, char...) o, al seu torn, d’un altre tipus d’objecte (el que s’anomena agregació o composició d’objectes). La idea és que un atribut representa una propietat determinada d’un objecte.
  • Rutines o mètodes: és un component d’un objecte que porta a terme una determinada acció o tasca amb els atributs. En principi, totes les variables i rutines d’un programa de Java han de pertànyer a una classe. De fet, en Java no hi ha noció de programa principal i els subrutines no existeixen com a unitats modulars independents, sinó que formen sempre part d’alguna classe.

9.1 Classes

una classe representa el conjunt d’objectes que comparteixen una estructura i un comportament comuns. Una classe és una combinació específica d’atributs i mètodes i pot considerar-se un tipus de dada de qualsevol tipus no primitiu. Així, una classe és una espècie de plantilla o prototip d’objectes: defineix els atributs que componen aquest tipus d’objectes i els mètodes que poden emprar-se per treballar amb aquests objectes. Encara que, d’altra banda, una classe també pot estar composta per mètodes estàtics que no necessiten d’objectes (com les classes construïdes en els capítols anteriors que contenen un mètode estàtic main). La declaració d’una classe segueix la següent sintaxi:

 class IdentificadorClase { // Declaraciones de atributos y metodos ...}

Convenció dels programadors en Java: els identificadors de les classes haurien de ser simples, descriptius i substantius i, en el cas de noms compostos, amb la primera lletra de cada un en majúscules. És convenient utilitzar les paraules completes i evitar els acrònims, llevat que l’abreviatura sigui molt més utilitzada que la forma no abreujada com a URL o HTML.

9.2 Instàncies

Una instància és un element tangible (ocupa memòria durant l’execució de el programa) generat a partir d’una definició de classe. Tots els objectes emprats en un programa han de pertànyer a una classe determinada.

Encara que el terme de vegades s’empra d’una manera imprecisa, un objecte és una instància d’una classe predefinida en Java o declarada per l’usuari i referenciada per una variable que emmagatzema la seva adreça de memòria. Quan es diu que Java no té punters simplement s’indica que Java no té punters que el programador pugui veure, ja que totes les referències a objecte són de fet punters en la representació interna.

En general, l’accés als atributs es realitza a través de l’operador punt, que separa l’identificador de la referència de l’identificador de l’atribut (idReferencia.idAtributo). Les trucades als mètodes per realitzar les diferents accions es duen a terme separant els identificadors de la referència i de el mètode corresponent amb l’operador punt (idReferencia.idMetodo(parametros)).

exemple senzill de classe i d’instància

El següent codi mostra la declaració de la classe Precio. La classe Precio consta d’un únic atribut (euro) i dos mètodes: un que assigna un valor a l’atribut (pone) sense tornar cap valor i un altre que retorna el valor de l’atribut (da).

/** * Ejemplo de declaracion de la clase Precio * double da() --> devuelve el valor almacenado en euros * void pone( double x ) --> almacena valor en euros */public class Precio { // Atributo o variable miembro public double euros; // Metodos public double da() { return this.euros; } public void pone(double x) { this.euros = x; }}

Gràficament, una classe pot representar-se com un rectangle.

Representació gràfica de la classe codePrecio / code

Figura 9.1 Representació gràfica de la classe Precio

l’anterior codi pot compilar:

$>javac Precio.java

generant l’arxiu de bytecodes Precio.class. Aquest fitxer no és directament executable per l’intèrpret, ja que el codi font no inclou cap mètode principal (main).Per poder provar el codi anterior, pot construir-se un altre arxiu amb el codi font que es mostra a continuació:

/** * Ejemplo de uso de la clase Precio */public class PruebaPrecio { public static void main (String args ) { Precio p; // Crea una referencia de la clase Precio p = new Precio(); // Crea el objeto de la clase Precio p.pone(56.8); // Llamada al metodo pone // que asigna 56.8 al atributo euros // Llamada al metodo da que devuelve el valor de euros System.out.println("Valor = " + p.da()); Precio q = new Precio(); // Crea una referencia y el objeto q.euros=75.6; // Asigna 75.6 al atributo euros System.out.println("Valor = " + q.euros); }} 

Representació gràfica de l'espai de la memòria utilitzat per les referències i instàncies de la classe codePrecio / code durant l'execució de l'mètode codemain / code de la classe codePruebaPrecio / code

Figura 9.2 Representació gràfica de l’ espai de la memòria utilitzat per les referències i instàncies de la classe Precio durant l’execució de l’mètode main de la classe PruebaPrecio

Explicació de l’exemple anterior

Per a poder treballar amb objectes s’haurà de seguir un procés de dos passos. El primer que ha de fer el programa és crear una referència o punter de la classe Precio amb l’identificador p. De manera similar a com es declara una variable d’un tipus primitiu, la declaració de l’identificador de la referència es realitza amb la sintaxi:

identificadorClase identificadorReferencia;// En el ejemplo anterior: Precio p;

Creació de la referència CODEP / code

Figura 9.3 Creació de la referència p

la referència o punter, p, té com a missió emmagatzemar l’adreça de memòria de (apuntar a) els components de la instància que encara no ha estat creada ni referenciada. En aquest moment es diu que la referència p, recent creada, emmagatzema una adreça de memòria nul·la (que no correspon a cap objecte) o null. El segon pas de l’procés per treballar amb objectes porta a la creació d’una nova instància referenciada per p, que es realitza amb la sentència:

Creació de la nova instància de la classe codePrecio / code referenciat per CODEP / code

Figura 9.4 Creació de la nova instància de la classe Precio referenciat per p

A aquesta operació se l’anomena també instanciació. Tot i que les dues operacions anteriors (creació de la referència i creació de la instància referenciada) poden realitzar-se conjuntament en la mateixa línia de codi:

identificadorClase identificadorReferencia = new identificadorClase();// En el codigo del ejemplo anterior: Precio q = new Precio();

Creació de la referència codeq / code i de la nova instància de la classe codePrecio / code referenciat per codeq / code

Figura 9.5 Creació de la referència q i de la nova instància de la classe Precio referenciat per q

el resultat de l’execució de el codi anterior són dues noves instàncies de la classe Precio referenciats respectivament per p i q. L’atribut euros de cadascuna de les noves instàncies de la classe Precio accessible a través del identificador de la referència i de l’operador punt (p.euros i q.euros). Els mètodes da i pone pertanyents a la classe Precio són accessibles a través de l’identificador de la referència i de l’operador punt (p.da() i p.pone(56.8) i q.da() i q.pone(75.6), respectivament). En el cas dels mètodes, la instància mitjançant la qual es realitza la trucada corresponent actua com un paràmetre o argument implícit de l’mètode.

Si s’assigna una referència a una altra mitjançant una sentència d’assignació, no es copien els valors dels atributs, sinó que es té com a resultat una única instància apuntada per dues referències diferents. Per exemple:

q = p; // Ahora p y q referencian al mismo objeto

Resultat de l'assignació de valors entre referències

Figura 9.6 Resultat de l’assignació de valors entre referències

En aquest cas, què passa amb la instància referenciada prèviament per q? Aquesta instància es queda sense referència (inaccessible). Això pot ser un problema en alguns llenguatges de programació, com és el cas de Pascal o de C, que utilitzen variables dinàmiques i que necessiten alliberar explícitament l’espai en memòria reservat per a les variables que deixaran de ser referenciades. La gestió dinàmica de la memòria sol ser una tasca molesta per al programador i molt donada a la proliferació d’errors d’execució. Per evitar aquests inconvenients, Java permet crear tantes instàncies com es vulgui (amb l’única limitació de la memòria que sigui capaç de gestionar el sistema), sense que el programador hagi de preocupar de destruir-les o alliberar-les quan ja no es necessitin.L’entorn d’execució de Java elimina automàticament les instàncies quan detecta que no es van a usar més (quan deixen d’estar referenciades). A aquest procés se li denomina recollida o recollida d’escombraries (garbage collection).

9.3 Modificadors de visibilitat

El modificador public indica que la component de l’mètode accessible fora de el codi de la classe a la qual pertany la component a través d’l’operador punt. El modificador private indica que la component només accessible a través dels mètodes de la pròpia classe. El modificador protected es veurà posteriorment. En el següent codi es declara l’atribut euros amb el modificador private.

/** * Ejemplo de declaracion de la clase PrecioPrivado * double da() --> devuelve el valor almacenado en euros * void pone( double x ) --> almacena valor en euros * euros --> Atributo de acceso privado */public class PrecioPrivado { // Atributo o variable miembro private double euros; private double euros; // Metodos publicos public double da() { return this.euros; } public void pone(double x) { this.euros = x; }}

Si es construeix un altre codi que intenti utilitzar directament l’atribut euros:

/** * Ejemplo de uso de la clase PrecioPrivado * double da() --> devuelve el valor almacenado en euros * void pone( double x ) --> almacena valor en euros * euros --> Atributo de acceso privado */public class PruebaPrecioPrivado { public static void main (String args ) { PrecioPrivado p = new PrecioPrivado(); // Crea instancia p.pone(56.8); // Asigna 56.8 a euros System.out.println("Valor = " + p.da()); // Asigna 75.6 a euros - ERROR p.euros=75.6; System.out.println("Valor = " + p.euros); // Tambien ERROR }}

es produirà un error de compilació:

$>javac PruebaPrecioPrivado.javapruebaPrecioPrivado.java:15: euros has private access in precioPrivado p.euros=75.6; ^ pruebaPrecioPrivado.java:16: euros has private access in precioPrivado System.out.println("Valor = " + p.euros); ^

ja que l’atribut euros només a través dels mètodes de la classe da i pone.

la utilització de l’modificador private serveix per implementar una de les característiques de la programació orientada a objectes: l’ocultació de la informació o encapsulació. Estrictament parlant, la declaració com a públic d’un atribut d’una classe no respecta aquest principi d’ocultació d’informació. Declarant com privats, no es té accés directe als atributs de l’objecte fora de el codi de la classe corresponent i només es pot accedir a ells de forma indirecta a través dels mètodes proporcionats per la pròpia classe. Un dels avantatges pràctiques d’obligar a l’ús d’un mètode per modificar el valor d’un atribut és assegurar la consistència de l’operació. Per exemple, un mètode que assigni valor a l’atribut euros d’un objecte de la classe Precio pot garantir que no se li assignarà un valor negatiu .

9.4 Classes niuades i internes

Una classe B es pot definir com a membre d’una altra classe A. l’estructura sintàctica és la següent:

class ClaseA { ... class ClaseB { ... }}

Es diu que ClaseB és una classe imbricada en la ClaseA. La classe imbricada només pot emprar-se dins de la classe contenidora. Aquest tipus de classes només es construeixen quan la classe imbricada només s’empra o té sentit dins de la classe contenidora. La classe imbricada pot declarar-se com static. En aquest cas la classe imbricada s’anomena classe imbricada estàtica. En cas contrari es denomina classe interna.

9.5 L’operador instanceof

L’operador instanceof retorna vertader o fals si un objecte pertany o no a una classe determinada. Sintaxi:

identificadorInstancia instanceof identificadorClase

Deixa un comentari

L'adreça electrònica no es publicarà. Els camps necessaris estan marcats amb *