Diferència entre revisions de la pàgina «M3 - Programació estructurada / Continguts UF2: Classes i biblioteques»

De wikiserver
Dreceres ràpides: navegació, cerca
(Sintaxi general)
(Sintaxi general)
Línia 352: Línia 352:
 
===Sintaxi general===
 
===Sintaxi general===
  
:*Tot el text amb la informació requerida per generar documentació usant javadoc s’escriu dins
+
:*Tot el text amb la informació requerida per generar documentació usant javadoc s’escriu dins de comentaris al codi font d’acord al format emprat per escriure múltiples línies.
de comentaris al codi font d’acord al format emprat per escriure múltiples línies.
 
  
 
:*No es poden usar dobles contrabarres (que serveixen per comentar una línia individual).
 
:*No es poden usar dobles contrabarres (que serveixen per comentar una línia individual).

Revisió del 19:38, 15 març 2018

Programes amb múltiples classes

  • La manera més directa de fer un programa modular és establir una correspondència un a un entre mòduls i fitxers on està escrit el codi font d’un programa.
  • Cada mòdul es representa amb un fitxer de codi font diferent.
  • En el cas de Java, un programa modular està compost de l’agregació de múltiples classes.

Què és una classe?

Tres consideracions des d'una perspectiva pràctica:

  • Un programa en Java. Els fitxers dels programes, pròpiament, són classes (al cap i a la fi, s’inicien amb la declaració public class...). En aplicar disseny descendent, el seu codi queda distribuït en un mètode principal (main), que indica la seva primera instrucció i el punt d’inici del seu flux de control, junt amb diferents mètodes addicionals que poden ser invocats directament.
  • Un repositori de mètodes. També s'usa el terme classe per referir-se a biblioteques de mètodes, que actuen com extensions en les instruccions disponibles per defecte en el llenguatge. Abans de poder fer-ho, però, cal inicialitzar-les correctament.
-L’exemple més clar és la classe Scanner, que ofereix un repertori de mètodes per controlar la lectura de dades des del teclat (nextLine(), nextInt(),hasNextFloat(), etc.).
  • Un tipus compost. Aquest mateix terme s'usa com a sinònim de tipus compost.
- l’exemple per antonomàsia és la classe String, utilitzada per referir-se a cadenes de text dins de Java. Els tipus compostos de Java permeten manipular dades complexes mitjançant la invocació de mètodes (charAt(...), indexof(...), etc.).

Semblences

- Els tres casos són exactament el mateix en darrera instància: codi font dins un fitxer anomenat NomClasse.java, amb la declaració public class NomClasse..., i estructurat com un seguit de mètodes declarats dins seu.
- Per tant, la classe Scanner ha estat desenvolupada per algú altre, dins d’un fitxer anomenat Scanner.java i que conté diferents mètodes.

Estructura d’un programa modular en Java

  • Totes les classes es codifiquen de la mateixa manera (com fitxers que contenen un seguit de mètodes que poden ser invocats).
  • Un programa és una seqüència ordenada d’instruccions que es van executant d’inici a fi.
- Mitjançant les estructures de control (selecció i repetició), és possible crear bifurcacions o bucles a la seqüència.
- Es poden trobar invocacions a mètodes, fent possible distribuir les instruccions en blocs diferents, que poden ser executats repetides vegades en diferents moments del procés.
- Tots els mètodes estan escrits dins un mateix fitxer, que conté el codi font de tot el programa.
- main és el mètode principal, el qual indica quina és la primera instrucció.
  • L’única diferència d’un programa modular en Java és que els mètodes, en lloc d’estar escrits tots en el mateix fitxer, estan distribuïts dins de diferents fitxers (diferents classes). tal com es contrasta a la figura 1.1.
  • Exemple, el programa modular es composa de tres fitxers diferents, anomenats Principal.java, Modul1.java i Modul2.java.
Classes i biblioteques
  • L’escriptura de mètodes en fitxers separats se sol fer d’acord a algun criteri d’ordre, com agrupar mètodes per funcionalitats semblants (una classe amb els mètodes relacionats amb operar amb arrays, una altra amb els que llegeixen dades des del teclat, etc.).
  • Per fer un programa modular cal decidir amb criteri com distribuir els diferents mètodes en diferents classes (i en quantes) i saber com invocar mètodes declarats a altres classes.
  • Main class: és l’única que disposa d’un mètode principal declarat en el seu codi.
  • Per executar un programa modular en Java, només cal executar aquesta classe principal. A partir d’aquí, l’execució de les diferents instruccions segueix el flux de control habitual, partint del mètode principal d’aquesta classe, tal com s’ha mostrat a la figura.
  • Les classes addicionals normalment tenen dos orígens. Poden ser classes creades per vosaltres mateixos, o bé creades per altres desenvolupadors. En qualsevol dels dos casos, totes estan declarades i codificades en fitxers .java per separat.

Definició de classes addicionals

  • Per dividir un programa en classes diferents, només cal crear tants fitxers com classes es vol, cadascun amb el seu nom i definició pròpia.
  • La classe principal ha de contenir com a mínim els mètodes main i inici.
  • La resta de classes contindrà els mètodes que es vulgui distribuir.
  • Excepte pel mètode principal a les classes addicionals, totes les classes són exactament iguals a nivell de sintaxi.

Ús de classes addicionals

  • En un programa modular, des d’una classe s’invoquen mètodes declarats a una classe diferent. Però cada mètode només està escrit un únic cop entre totes les classes del programa.
  • Per invocar mètodes escrits en fitxers diferents, primer cal un pas previ d’inicialització, a partir del qual es permet la invocació dels mètodes externs. En dur a terme aquest procés, s’assigna un identificador a partir del qual és possible invocar els mètodes d’aquella classe, usant-lo com a prefix a la invocació.
  • La sintaxi per fer-ho és la següent:
NomClasse identificador = new NomClasse();
identificador.nomMètode(paràmetres);
  • La inicialització només es fa una vegada.
  • L’àmbit i la validesa de l’identificador és el mateix que una variable.

Biblioteques de classes: paquets

  • Quan el nombre de classes resultants sigui força gran és convenient organitzar conjunts de classes dins d’un programa. Això permet aplicar modularitat a conjunts de classes en bloc, i també fer-les més fàcils de localitzar i gestionar.
  • Una biblioteca de classes, o package en Java, és un conjunt de classes vinculades entre elles d’acord a algun criteri temàtic o d’organització del seu codi.
  • Els criteris per decidir com dividir les classes d’un programa en conjunts de paquets (packages) diferents són subjectius.
  • Malgrat que els programes fets i que farem tenen un nombre de classes massa limitat com per justificar de manera clara l’ús de paquets, es tracta d’un element prou important de Java com per fer necessari conèixer el seu funcionament.

Definició de paquets

  • Per assignar un conjunt de classes a un package, primer cal triar un identificador (autoexplicatiu), que servirà

com el nom d’aquest.

  • Per fer que una classe hi pertanyi, a la primera línia del seu fitxer amb el codi font s’ha d'escriure la sentència següent:
package identificadorPackage;
  • El concepte package en Java no té una entitat pròpia diferenciada, serà donat implícitament per totes les classes que es declaren com a part d’ell en el seu codi font.
  • Convenció de codi: els noms dels packages s’escriuen sempre tots en minúscula i separant paraules diferents per

un punt. Per exemple:

package uf2.apartat1.exemple1;
  • Totes les classes del Java pertanyen a algun paquet. En cas de no incloure cap sentència import, es considera que aquella classe pertany a un package especial anomenat per defecte (default package). No és possible crear una classe que “no pertanyi a cap package”.
  • La manera com té el Java d’ordenar les classes dins un programa en packages (inclòs el package per defecte) comporta dues restriccions que heu de tenir sempre en compte:
- Donada una classe, aquesta únicament pot pertànyer a un package.
- Donat un paquet, a dintre seu mai hi poden haver dues classes amb el mateix nom.

Ús de classes d’altres paquets

  • El nom qualificat d’una classe és la combinació de l’identificador del seu package junt amb el seu nom, separats per un punt.
  • Només es poden usar directament classes amb què comparteixi el mateix nom de paquet. Si s’usa una classe d’un de diferent, el compilador donarà un error, dient que no la reconeix.
  • Java ofereix tres maneres per indicar quina s’està usant:
-1. Inicialització usant el nom qualificat per al cas de classes d’altres paquets:
package uf2.apartat1.exemples;

public class RegistreNotes {
  ...
  //Ús del nom qualificat per accedir a una classe d’un altre package
  utilitats.arrays.CalculsArrayReals calculador = new utilitats.arrays.CalculsArrayReals();
  ...
}

package utilitats.arrays;

public class CalculsArrayReals {
  //Codi
  ...
}
- 2. Importació explícita a la capçalera del fitxer de codi font, entre la declaració del package i

la declaració public class.... Cal especificar el nom qualificat de la classe que es vol usar.

La sintaxi general és:
import nomQualificat;
  • Cal posar tantes sentències import com correspongui.
  • Les relacions de jerarquia entre els identificadors del package no importen, cal posar cada classe amb el seu package explícitament, una per una.
package uf2.apartat1.exemples;

//Cal importar la classe "CalculsArrayReals", ja que és d’un altre package
import utilitats.arrays.CalculsArrayReals;

public class RegistreNotes {
  //Codi
  ...
}

package utilitats.arrays;
//No s’usa cap classe fora d’aquest package, no s’importa res

public class CalculsArrayReals {
  //Codi
  ...
}
- 3. Importació general. Permet importar automàticament totes les classes dins una biblioteca. Aquest es fa servir sovint quan es volen usar moltes classes del mateix package i importar-les una a una es fa pesat. Es tracta d’usar un asterisc, “*”, en lloc del nom de la classe en el nom qualificat. Aquest fa de comodí i equival a dir “absolutament totes les classes del package”.
package uf2.apartat1.exemples;

//S’importarien totes les classes del package utilitats.arrays
import utilitats.arrays.*;

public class RegistreNotes {
  //Codi
  ...
}

L’API del llenguatge Java

  • Els llenguatges de programació incorporen biblioteques de mòduls auxiliars que ja han estat completament desenvolupats pels creadors del llenguatge o altres col·laboradors.
  • Aquests mòduls ofereixen funcionalitats que resolen tasques de propòsit general i que poden ser d’utilitat en molts programes.
  • El kit de desenvolupament (JDK) de Java consta d'un repositori molt extens de classes, organitzades per diferents packages d’acord a la seva temàtica, que poden ser accedides lliurement en realitzar qualsevol programa. Aquest repositori és el que s’anomena l’API de Java.
  • Trobar la classe, en la documentació de Java, que conté els mètodes ideals per a cada cas, si és que existeix inviable.
  • Per usar la documentació, primer cal cercar quina classe pot ser la que realitza les tasques que voleu dur a terme, a partir d’una font bibliogràfica externa o d’una cerca a internet, i llavors referir-se a l’API només per estudiar amb més detall quins mètodes ofereix.
Classes i biblioteques
  • Com a exemple, entre els paquets que contenen les classes més populars, podeu trobar:
- java.lang: conté totes les classes vinculades a operacions essencials dels tipus de dades del llenguatge.
- java.util: una mena de calaix de sastre amb classes de propòsit general.
- java.io: conté totes les classes vinculades a entrada / sortida (tractament de fitxers).
- javax.swing: conté les classes bàsiques vinculades a la creació d’interfícies gràfiques.

Mètodes estàtics

  • Els mètodes estàtics poden ser invocats sense haver d’inicialitzar la seva classe. S’identifiquen perquè a la documentació apareixen marcats

amb la paraula clau static.

  • Gairebé tots els mètodes de les classes java.lang.Math i java.util.Arrays són estàtics.
Classes i biblioteques
  • Sintaxi: posar com a prefix el nom de la classe directament.
  • El seu comportament és idèntic a qualsevol altre mètode.
  • Exemple: mètode estàtic sqrt definit a la classe Math, el qual accepta un únic paràmetre d’entrada de tipus real, per invocar-lo i desar el resultat en una variable només caldria el codi que es mostra tot seguit. En aquest cas, es calcula l’arrel quadrada de 36.
double resultat = Math.sqrt(36);

La classe Math

  • Pertany al package java.lang, i per tant pot ser usada sense haver d’importar-la.
  • Ofereix un ventall de mètodes estàtics per realitzar operacions matemàtiques avançades, que no es poden dur a terme amb cap dels operadors aritmètics de què disposa Java (suma, resta, multipliació, divisió i mòdul).
Mètode Descripció Exemples
abs( x ) valor absolut de x abs( 23.7 ) és 23.7 / abs( –23.7) és 23.7
ceil( x ) arrodoneix x a l’enter més petit que no sigui menor de x ceil( 9.2 ) és 10.0 / ceil( -9.8 ) és -9.0
cos( x ) cosinus trigonomètric de x (x està en radians) cos( 0.0 ) és 1.0
exp( x ) mètode exponencial e x exp( 1.0 ) és 2.71828
floor( x ) arrodoneix x a l’enter més gran que no sigui més gran que x floor( 9.2 ) és 9.0 / floor( -9.8 ) és -10.0
log( x ) logaritme natural de x (base e) log( Math.E ) és 1.0
max( x, y ) el valor més gran de x i y max( 2.3, 12.7 ) és 12.7
min( x, y ) el valor més petit de x i y min( 2.3, 12.7 ) és 2.3
pow( x, y ) x elevat a la potència y pow( 2.0, 7.0 ) és 128.0
sin( x ) sinus trigonomètric de x (x està en radians) sin( 0.0 ) és 0.0
sqrt( x ) arrel quadrada de x sqrt( 900.0 ) és 30.0
tan( x ) tangent trigonomètrica de x (x està en radians) tan( 0.0 ) és 0.0

La classe Arrays

  • Proporciona mètodes estàtics per manipular taules com: sort per ordenar, binarySearch per buscar en una taula ordenada, equals per comparar-les i fill per posar valors.
  • En el programa següent podem veure la utilització d’aquests mètodes.
public class UsArrays {

  private int arrayInt[] = {1, 2, 3, 4, 5, 6};
  private double arrayDouble[] = {8.4, 9.3, 0.2, 7.9, 3.4};
  private int arrayIntPle[], copiaArrayInt[];

  public UsArrays() {

    arrayIntPle = new int[10];
    copiaArrayInt = new int[arrayInt.length];
    Arrays.fill(arrayIntPle, 7);
    Arrays.sort(arrayDouble);
    System.arraycopy(arrayInt, 0, copiaArrayInt, 0, arrayInt.length);
  }

  public void imprimirArrays() {

    System.out.print("arrayDouble: ");
    for (double valorDouble : arrayDouble) {
      System.out.printf("%.1f ", valorDouble);
    }
    System.out.print("\narrayInt: ");
    for (int valorInt : arrayInt) {
      System.out.printf("%d ", valorInt);
    }  
    System.out.print("\narrayIntPle: ");
    for (int valorInt : arrayIntPle) {
      System.out.printf("%d ", valorInt);
    }
    System.out.print("\ncopiaArrayInt: ");
    for (int valorInt : copiaArrayInt) {
      System.out.printf("%d ", valorInt);
    }
    System.out.println("\n");
  }

  public int buscarUnInt(int valor) {

    return Arrays.binarySearch(arrayInt, valor);
  }

  public void imprimirIgualtat() {

    boolean b = Arrays.equals(arrayInt, copiaArrayInt);
    System.out.printf("arrayInt %s copiaArrayInt\n",(b ? "==" : "!="));
    b = Arrays.equals(arrayInt, arrayIntPle);
    System.out.printf("arrayInt %s arrayIntPle\n",(b ? "==" : "!="));
  }

  public static void main(String args[]) {

    UsArrays usArrays = new UsArrays();
    usArrays.imprimirArrays();
    usArrays.imprimirIgualtat();
    int ubicacio = usArrays.buscarUnInt(5);
    if (ubicacio >= 0) {
      System.out.printf("S'ha trobat el 5 en el element %d de arrayInt\n", ubicacio);
    } else {
        System.out.println("No s'ha trobat el 5 en arrayInt");
      }
    ubicacio = usArrays.buscarUnInt(8763);
    if (ubicacio >= 0) {
      System.out.printf("S'ha trobat el 8763 en el element %d de arrayInt\n", ubicacio);
    } else {
        System.out.println("No s'ha trobat el 8763 en arrayInt");
      }
  }
}
  • El mètode binarySearch funciona de la següent manera: si es troba el valor retorna l’índex de l’element, en cas contrari torna un valor negatiu. El valor negatiu es basa en el punt d’inserció de la clau de cerca: l’índex on s’hauria d’inserir la clau si s’hagués de fer una operació d’inserció. Una vegada el mètode determina el punt d’inserció, canvia el signe d’aquest a negatiu i li resta un. Per exemple en el codi anterior el punt d’inserció per al valor 8763 es l’índex 6, per tant el mètode retorna -7. Aquest valor de retorn és útil per agregar elements en una taula ordenada.
-Si passem una taula desordenada el valor retornat és indefinit.
-Si hi ha valors repetits, el mètode no garanteix, quin d’ells troba.

Javadoc

  • Eina auxiliar proporcionada pel kit de desenvolupament de Java (JDK), que permet generar automàticament documentació relativa a classes Java a partir de comentaris dins del seu codi font.
  • Processa els fitxers de codi font de les classes d’un programa, de manera que cerca certes paraules clau distintives inserides als comentaris i a partir d’aquestes genera automàticament documentació en format HTML.
  • Convé crear el codi font del programa i aquests comentaris alhora, usant les paraules clau corresponents.
  • La documentació de l’API de Java va estar generada amb aquesta eina.
  • Totes les classes que venen amb les biblioteques de Java es van programar comentant el seu codi font d’acord al format adient. En acabar, només va caldre executar javadoc per crear l’HTML amb tota la documentació.

Sintaxi general

  • Tot el text amb la informació requerida per generar documentació usant javadoc s’escriu dins de comentaris al codi font d’acord al format emprat per escriure múltiples línies.
  • No es poden usar dobles contrabarres (que serveixen per comentar una línia individual).
/** Línia 1 de comentari.
* Línia 2 de comentari.
* ...
* Línia N del comentari.
**/
  • Es poden inserir en les línies immediatament abans tant de la declaració de la classe (public class ...) com dels mètodes.
  • El que s’escrigui en les diferents línies del comentari serà l’explicació detallada d’aquella classe o mètode a la documentació final.
  • Exemple: l’esquelet de classe següent aportaria la documentació de la classe pròpia i dels seus dos mètodes.
package uf2.apartat3.exemples;

/** Tot just aquest text serà la documentació de la classe.
* El que estigui escrit s’inclourà directament a l’HTML resultant.
* Aquesta és una classe ben documentada.
**/

  public class ClasseComentada {
  /** Aquest és el seu primer mètode.
  * Només es mostra l’esquelet, no cal codi de moment.
  * És important veure com funcionen els comentaris per poder usar el javadoc
  **/

  public void unMetode() {
  ...
  }
  /** Un altre mètode, més escàs en documentació.
  **/

  public void unAltreMetode() {
  ...
  }
}
  • Tot el text escrit als comentaris es transforma en text normal en HTML, en un mateix

paràgraf.

  • Es poden usar comandes en HTML per afegir efectes especials (negretes, cursiva. etc.) o estructures de text una mica més complexes (com llistes ordenades o enumerades), en el text d’aquests comentaris.
  • Exemple: l’ordre HTML ... serveix per fer que un text aparegui en negreta, i l’ordre
      ...
    permet crear una llista enumerada:
/** Aquest és un mètode extra.
* Ara conté una <b>llista d’ítems</b>.
* <ol>
* <li> Ítem 1.
* <li> Ítem 2.
* <li> Ítem 3.
* <li> Ítem 4.
* </ol>
**/

public void unTercerMetode() {
...
}

Paraules clau

Hi ha alguns aspectes d’una classe o un mètode que són especialment rellevants, com el seu autor, paràmetres d’entrada o valor de retorn. A part d’una descripció general, val la pena disposar d’una llista clara de quins són i el valor esperat, de manera que destaquin més en el document HTML resultant. Per això, hi ha un seguit de paraules clau que es poden usar un cop finalitzat el text, de manera que s’indica en el javadoc aquesta informació addicional. Totes les paraules clau queden identificades perquè es precedeixen d’un símbol ”@”, de manera que no puguin ser confoses per text normal, part de la descripció. Després de la paraula clau, es pot escriure una línia de text qualsevol que es considera la seva informació associada.

Tot seguit veureu algunes de les paraules clau més usades. y @author. Aquesta paraula clau només s’usa després del text associat a la descripció de la classe. Indica qui n’ha estat l’autor. y @param. Aquesta paraula clau només s’usa després del text associat a la descripció d’un mètode i descriu un dels seus paràmetres. Caldrà afegir-ne tantes paraules clau d’aquest tipus, en diferents línies consecutives, com paràmetres té el mètode. El text ha de començar per l’identificador del paràmetre d’entrada que es vol descriure, i tot seguit s’escriu la seva descripció, on caldria explicar per a què serveix.

/** Un mètode amb paràmetres.

  • @param unParametre Aquest paràmetre serveix per fer una cosa.
  • @param unaltre Parametre Aquest paràmetre diferent serveix per fer una altra cosa.
    • /

public void unMetodeParametritzat(int unParametre, int altreParametre) { ... }

y @returns. Aquesta paraula clau només s’usa després del text associat a la descripció d’un mètode i descriu què avalua el mètode (el valor retornat). Normalment s’escriu després de les paraules clau @params, si n’hi ha. Si un mètode no retorna res (void), no cal incloure’l. El text associat és directament la descripció.

/** Un mètode amb paràmetres.

  • @param unParametre Aquest paràmetre serveix per fer una cosa.
  • @param unaltre Parametre Aquest paràmetre diferent serveix per fer una altra cosa.
  • @returns Un valor que depèn dels dos paràmetres.
    • /

public int unMetodeParametritzat(int unParametre, int altreParametre) { ... }

@see. Aquesta paraula clau es pot usar tant després de la descripció d’un mètode com d’una classe. Serveix per referir-se a la pàgina de documentació d’altres classes dins el mateix programa, en els casos de programes modulars compostos per diferents classes. Bàsicament diu: “Per a més informació, veure també la documentació de...”. No serveix per referir-se a qualsevol classe, només funciona amb classes de les quals es disposa el codi font comentat en aquest format. Dins d’un IDE, normalment seran classes dins del mateix projecte. Com a text associat, cal posar el nom qualificat de la classe a què es refereix.

/** Tot just aquest text serà la documentació de la classe.

  • El que estigui escrit s’inclourà directament a l’HTML resultant.
  • Aquesta és una classe ben documentada.
  • @author Albert
  • @see utilitats.arrays.CalculsArrays
    • /

public class ClasseComentada { ... }