# Qué ès ?

Java és un llenguatge de programació amb tres característiques fonamentals:
* És independent de plataforma: Java és un llenguatge interpretat, però amb una característica que el fa especial. El seu codi font és primer transformat, per compilació, en un llenguatge anomenat ByteCode. Quan es vol executar, aquest Bytecode ha de ser executat per un interpret, anomenat Màquina Virtual, que el transforma en llenguatge màquina i el lliura al sistema operatiu. Per tant, un programa Java un cop compilat amb ByteCode, podrà ser executat en qualsevol plataforma que disposi d'una màquina virtual de Java.
* És orientat a objectes: Un programa orientat a objectes està compost per un conjunt d'entitats o objectes que interactuen intercanviant missatges o dades, en compte d'estar format per un conjunt de funcions. Els llenguatges orientats a objectes faciliten la programació d'aplicacions ja que representen la informació d'una forma més propera a la realitat.
* És robust i segur: Java permet gestionar de forma molt eficient i senzilla les errades de programari, així com controlar l'accés als objectes i als seus mètodes.

# Objectes i classes
## Què són ?

Un objecte de programari representa un objecte de la vida real o qualsevol altre concepte al que es pugui associar un estat i un comportament.
L'estat d'un objecte està format per un conjunt de característiques que el defineixen. En el cas del programari, l'estat es guarda a les variables.
El comportament, d'altra banda, el conformen un conjunt d'accions que es poden fer sobre un objecte per a canviar el seu estat. En el cas del programari, el comportament es representa amb mètodes.
Exemple: Objecte Avió
Una classe representa un conjunt d'objectes amb variables i mètodes comuns. Per exemple, la classe Avió representa a tots els objectes avió. A un objecte concret d'una classe se l'anomena instància. Les classes es representen mitjançant codi en un determinat llenguatge de programació.
Exemple: Classe Avió en Java

## Funcionament

Una classe es defineix en un fitxer que porta el mateix nom que la classe, amb l'extensió .java.
La seva definió es fa amb la directiva class que pot anar precedida per alguna de les següents directives (en l'ordre en què es presenten):
* public: Qualsevol altra classe hi pot accedir. En cas de no indicar-se, únicament hi poden accedir classes del mateix paquet
* abstract: No es poden crear objectes d'aquesta classe
* final: No es poden derivar altres classes d'aquesta classe

## Directives de control d'accés

Una classe pot decidir qui podrà accedir als seus mètodes o variables utilitzant les directives private, protected i public. Els efectes d'aquestes directives són:
| Directiva/Pot accedir | Classe | Paquet | Subclasse | Tothom |
| private | Sí | No | No | No |
| protected | Sí | Sí | Sí | No |
| public | Sí | Sí | Sí | Sí |
| no especificat | Sí | Sí | No | No |

## Directives de modificació del comportament

Hi ha diverses directives de modificació del comportament, que s'apliquen de forma diferent a les variables i als mètodes. Veiem una taula de resum:
| Directiva/Aplicació | Variable | Mètode |
| static | És una variable de la classe, no de l'objecte | És un mètode de la classe, no de l'objecte |
| final | És una constant | No pot ser sobreescrit per una classe derivada |
| abstract | No aplicable | El mètode ha de ser implementat en una classe derivada |

## Constructors

Una classe pot definir constructors, que són mètodes especial que porten el mateix nom que la classe i s'utlitzen per a crear els objectes d'aquesta classe. A les classes que no defineixen cap constructor, Java els hi crea un constructor buid.
Es poden definir tants constructors d'una classe com es vulgui, sempre que tinguin diferents arguments. Un constructor no pot retornar cap valor.
Exemple: Constructor de la classe AvioCarrega

## Creació d'objectes d'una classe

Per a definir objectes d'una classe, s'utilitza la directiva new.
Exemple: Creació d'objectes de la classe AvioCarrega

# Paquets
## Què són ?

Els paquets són agrupacions de classes utilitzats per a facilitar la seva búsqueda i ús, evitar conflictes de noms i controlar-ne l'accés.

## Nomenclatura

Els noms de paquet es formen amb paraules separades per punts. Per convenció, comencen amb el nom de domini invertit de l'empresa o institució que els ha desenvolupat.
Exemple: Si desenvolupem algun paquet a l'Àrea de sistemes d'informació i comunicació de la Universitat de Lleida dins del projecte Campus Virtual, el nom hauria de començar per ca.udl.asic.campusv
D'aquesta forma, identifiquem fàcilment la procedència dels paquets i, per tant, de les classes que contenen.

## Espai de noms

Els paquets ens serveixen també per a resoldre conflictes entre noms de les classes. Imagineu que volem desenvolupar una classe i anomenar-la String. Sense el concepte de paquets, això no seria possible, donat que en el llenguatge Java ja existeix una classe amb aquest nom.
Afortunadament, amb el concepte de paquet, aquest problema desapareix donat que java.lang.String mai es podrà confondre amb ca.udl.asic.projecte.String.

## Control d'accés

Com hem vist, Java ofereix mecanismes de control d'accés a les classes, a les seves variables i als seus mètodes. Amb el concepte de paquet, introduïm un nivell més al mecanisme, de forma que es pot limitar l'accés a classes del mateix paquet.

## Creació de paquets

Quan volem definir una classe com a pertanyent a un paquet, utilitzem la directiva package a l'inici del fitxer que conté la classe.
Exemple: Declarem la classe Avió com a pertanyent al paquet ca.udl.asic.estiu
Per convenció, les classes es guarden en el sistema de fitxers utilitzant una jerarquia de directoris que reflecteix el paquet al qual pertanyen.
Exemple: Les classes del paquet ca.udl.asic.estiu es guardarien al directori ca/udl/asic/estiu/.

## Importació de paquets

La importació de paquets és un mecanisme que ens evita haver d'escriure el nom complet d'una classe, inclòs el nom del paquet, quan la utilitzem.
Exemple: Sense importació, hem d'utilitzar el nom complet d'una classe per a fer-hi referència
Exemple: Amb importació
A les sentències d'importació podem importar una sola classe o totes les classes d'un determinat paquet, utilitzant l'asterisc.

## Exemples

Exemples de paquets dins del mateix Java son:
* java.lang: Agrupa les classes fonamentals del llenguatge Java com System, String ...
* java.io: Agrupa les classes relacionades amb la gestió de l'entrada/sortida
* java.math: Agrupa les classes relacionades amb els càlculs matemàtics
* java.net: Agrupa les classes relacionades amb la gestió de les comunicacions per xarxa
* java.sql: Agrupa les classes relacionades amb la connexió amb bases de dades relacionals
* java.util: Agrupa classes d'utilitat com col·leccions, dates, diccionaris ...

# Herència
## Què significa ?

L'herència, en els llenguatges de programació orientada a objectes, és el nom que es dóna a la capacitat que tenen els objectes de derivar d'altres objectes, heretant les característiques de l'objecte pare i fent possible la seva extensió mitjançant l'agregació de variables i mètodes.

## Funcionament

En Java, la única herència permesa és l'herència simple, és a dir, una classe pot derivar d'una i solament una classe pare. La declaració d'una classe com a derivada (o filla) d'una altra es fa utilitzant la directiva extends.
Exemple: Declarem AvioCarrega com a classe derivada d'Avio
Pel fet de ser una classe derivada d'Avio, AvioCarrega hereta totes les variables i mètodes d' Avio, excepte el constructor. Podrà utilitzar tots els mètodes d' Avio que no estiguin declarats com a private com si estiguessin declarats en el seu propi codi.
Exemple: Cridem al mètode Pintar d'AvioCarrega, tot i que en el seu codi font no consta aquest mètode

# Polimorfisme
## Què significa ?

Polimorfisme és la capacitat ens ofereixen els llenguatges de programació orientada a objetes per a reescriure mètodes en classes derivades que s'han definit a la classe pare. Una classe pot decidir que cap classe derivada pugui reescriure un mètode marcant-lo com a final.

## Funcionament

Una classe derivada pot reescriure un mètode definit en la classe pare tornant-lo a definir en el seu propi codi.
Exemple: AvioCarrega sobreescriu el mètode pinta d'Avio
Una classe derivada pot cridar a un mètode de la classe pare amb la directiva super.
Exemple: AvioCarrega sobreescriu el mètode pinta d' Avio cridant al mètode pinta d' Avio i afegint informació

# Interfícies i implementacions
## Què és ?

Una interfície es defineix mitjançant un conjunt de mètodes sense implementar, i tota classe que declari que implementa la interfície està obligada a implementar tots aquests mètodes. Per tant, una interfície és un contracte entre una classe i els seus usuaris que garanteix que determinats mètodes tenen implementació. Java posseeix un mecanisme que li permet simular l'herència múltiple, a través d'interfícies. Per tant, una interfície és una col·lecció de noms de mètodes sense definicions reals que indiquen que una classe té un conjunt de comportaments, a més dels quals la classe hereta de les seves superclasses.

## Funcionament

Exemple: Definició de la interfície ControlVelocitat
Una classe que implementi aquesta interfície haurà d'implementar els seus mètodes
Exemple: Comproveu que aquesta classe és INCORRECTA, i no compila
Exemple: Comproveu que aquesta classe sí compila

# Classes d'utilitat

La JDK disposa de moltes classes d'utilitat que ajuden el programador a dur a terme accions comunes. Per a conèixer el seu funcionament és imprescindible consultar la documentació de la versió de JDK.
La documentació de la versió que nosaltres utilitzem es pot trobar aquí.
Els paquets de més utilitat són els que s'han comentat a l'apartat que parla dels paquets. A les pròximes seccions parlarem de dos tipus de classes d'utilitat molt importants.

# Entrada/Sortida

L'entrada/sortida inclou totes les operacions de comunicació entre una aplicació i la resta del món. Aquesta comunicació es pot fer fonamentalment per tres vies:
* Mitjançant l'entrada i sortida estàndards
* Mitjançant fitxers
* Mitjançant una xarxa de comunicacions: Aquest cas no el veurem en aquest curs

## I/O Streams o fluxes d'entrada/sortida

L'entrada/sortida a Java es fa mitjançant Streams (fluxes) d'entrada/sortida. Aquests fluxes poden ser de dos tipus:
* Fluxe de lectura: Acumula dades que reb del dispositiu d'entrada associat a ell i facilita mètodes per accedir a aquesta informació
* Fluxe d'escriptura: Facilita mètodes per acumular dades i els traspassa al dispositiu de sortida associat.
Els streams més comodes d'utilitzar son aquells que permeten llegir o escriure línies, BufferedReader i BufferedWriter. El problema comú d'utilitzar aquests fluxes és convertir el mecanisme directe d'obtenció de dades a aquest tipus de fluxe. Veurem com fer-ho en cada cas.

## Entrada/sortida estàndard

La classe System és la que ens permet comunicar-nos per l'entrada/standard. Per a fer-ho, utilitzarem les seves variables in, out i err que són streams de tipus InputStream, PrintStream i PrintStream respectivament.
Veiem exemples del seu funcionament.
Exemple: Vegeu la classe HolaMon per a veure com escriure un missatge per la sortida estàndard
Exemple: Lectura d'informació de l'entrada standard de forma directa
Exemple: Lectura d'informació de l'entrada standard amb BufferedReader

## Fitxers

La lectura i escriptura de fitxers requereix la utilització de la classe File, a partir de la qual es creen streams per llegir o escriure al fitxer.
Exemple: Lectura i escriptura de fitxers amb FileReader i FileWriter
Exemple: Lectura i escriptura de fitxers amb BufferedReader i BufferedWriter

# Col·leccions

Les col·leccions son objectes que agrupen a altres objectes. La forma d'agruparlos diferencia una col·lecció d'una altra.
Tipus de col·leccions:
* Set: Conté elements sense ordre i no pot contenir elements duplicats
* List: Conté elements ordenats (es pot especificar la seva posició) i pot contenir duplicats
* Map: Vincula una clau amb cada objecte, de forma que es pot accedir directament als elements per la seva clau. No pot contenir claus duplicades
Java implementa aquests tipus de col·leccions amb diverses classes, de la que caldrà consultar el seu funcionament.