Structuri de Date în Java...

38
1 Structuri de Date în Java (III) Definirea unei clase (complet) Supraîncărcarea (overloading) Modificatori de acces Moştenire. Interfeţe Clase abstracte Polimorfism Suprascrierea (overriding) Clasa Object. Metode suprascrise: toString, clone, equals Compile time vs. runtime Moştenire vs. compoziţie Excepţii. Specificare şi tratare Nested classes vs. inner classes Clase locale şi clase anonime

Transcript of Structuri de Date în Java...

Page 1: Structuri de Date în Java (III)vega.unitbv.ro/~galmeanu/java/suport/curs-3/doc/java-curs-3.pdfStructuri de Date în Java (III) Definirea unei clase (complet) Supraîncărcarea (overloading)

1

Structuri de Date în Java (III)● Definirea unei clase (complet)● Supraîncărcarea (overloading)● Modificatori de acces● Moştenire. Interfeţe● Clase abstracte● Polimorfism● Suprascrierea (overriding)● Clasa Object. Metode suprascrise: toString, clone, equals● Compile time vs. runtime● Moştenire vs. compoziţie● Excepţii. Specificare şi tratare● Nested classes vs. inner classes● Clase locale şi clase anonime

Page 2: Structuri de Date în Java (III)vega.unitbv.ro/~galmeanu/java/suport/curs-3/doc/java-curs-3.pdfStructuri de Date în Java (III) Definirea unei clase (complet) Supraîncărcarea (overloading)

2

Definirea unei clase

● Şablonul definirii unei clase:

[<tip acces>] [abstract / final] class <className>[extends <superClassName>][implements <interfaceNames>] {

// constructori// metode// variabile membre

}

Page 3: Structuri de Date în Java (III)vega.unitbv.ro/~galmeanu/java/suport/curs-3/doc/java-curs-3.pdfStructuri de Date în Java (III) Definirea unei clase (complet) Supraîncărcarea (overloading)

3

Supraîncărcarea (overloading)

● O clasă poate avea două metode cu acelaşi nume doar dacă listele lor de parametri sunt diferite

● Exemplu:● void maxx () { ... }● void maxx (int x) { ... }● Java ştie care metodă o va chema pe baza

semnăturii● Exemplu:● maxx (7); // cheamă a doua metodă

Page 4: Structuri de Date în Java (III)vega.unitbv.ro/~galmeanu/java/suport/curs-3/doc/java-curs-3.pdfStructuri de Date în Java (III) Definirea unei clase (complet) Supraîncărcarea (overloading)

4

Constructori supraîncărcaţi

● O clasă poate avea mai mulţi constructori:

public class BankAccount {private int amount = 10;// iniţializare înainteapublic BankAccount () { // constructorului

// ...}public BankAccount (int amount) {

this.amount = amount;}

Page 5: Structuri de Date în Java (III)vega.unitbv.ro/~galmeanu/java/suport/curs-3/doc/java-curs-3.pdfStructuri de Date în Java (III) Definirea unei clase (complet) Supraîncărcarea (overloading)

5

Tipuri de acces

● Membrii unei clase pot avea diferite tipuri de acces

● Există patru tipuri de acces:● public – orice clasă din orice pachet● protected – orice clasă derivată (subclasă) are

acces● (default) – doar clasele din acelaşi pachet● private – accesibil doar din interiorul clasei

Page 6: Structuri de Date în Java (III)vega.unitbv.ro/~galmeanu/java/suport/curs-3/doc/java-curs-3.pdfStructuri de Date în Java (III) Definirea unei clase (complet) Supraîncărcarea (overloading)

6

Moştenire

● Permite claselor să definească aceeaşi funcţionalitate ca şi clasa de bază

● Scade complexitatea sistemelor mari

● Derivare:● Java permite doar o singură clasă de bază● Se defineşte cu cuvântul cheie extends

Page 7: Structuri de Date în Java (III)vega.unitbv.ro/~galmeanu/java/suport/curs-3/doc/java-curs-3.pdfStructuri de Date în Java (III) Definirea unei clase (complet) Supraîncărcarea (overloading)

7

Interfeţe● Interfaţa este specificarea unei clase● Declară metodele (publice) dar nu le defineşte● Interfeţele nu au constructori● O clasă ce implementează o interfaţă trebuie să-i

definească metodele● Şablon:

[<tip acces>] interface <interfaceName>[extends <interfaceNameList>] {

// declaraţii de metode// declaraţii de constante

}

Page 8: Structuri de Date în Java (III)vega.unitbv.ro/~galmeanu/java/suport/curs-3/doc/java-curs-3.pdfStructuri de Date în Java (III) Definirea unei clase (complet) Supraîncărcarea (overloading)

8

Exemplu de interfaţă

public interface BankAccount {public void withdraw (int amount);public void deposit (int amount);public int getBalance ();public final int maxNoOfWithdraws = 5;

}

// constanta din interfaţă se iniţializează la declarare

Page 9: Structuri de Date în Java (III)vega.unitbv.ro/~galmeanu/java/suport/curs-3/doc/java-curs-3.pdfStructuri de Date în Java (III) Definirea unei clase (complet) Supraîncărcarea (overloading)

9

Implementarea interfeţeipublic class CheckingAccount implements BankAccount {

private int balance;public CheckingAccount (int initial) {

balance = initial;}// implementăm toate metodele interfeţei BankAccountpublic void withdraw (int amount) {

balance -= amount; // puteam scrie balance = balance - amount

}public void deposit (int amount) {

balance += amount; // similar, balance = balance + amount}public int getBalance () {

return balance;}

}

Page 10: Structuri de Date în Java (III)vega.unitbv.ro/~galmeanu/java/suport/curs-3/doc/java-curs-3.pdfStructuri de Date în Java (III) Definirea unei clase (complet) Supraîncărcarea (overloading)

10

Clase abstracte● Sunt o îngemănare a claselor şi interfeţelor● pot avea metode definite (cu corp)● pot avea variabile membre

● Se definesc ca şi o clasă, prefixată însă cu cuvântul cheie abstract

● Conţin cel puţin o metodă nedefinită (doar declarată), definind însă metodele comune cunoscute

Page 11: Structuri de Date în Java (III)vega.unitbv.ro/~galmeanu/java/suport/curs-3/doc/java-curs-3.pdfStructuri de Date în Java (III) Definirea unei clase (complet) Supraîncărcarea (overloading)

11

Exemplu de clasă abstractăpublic abstract class BankAccount {

protected int balance;public int getBalance () {

return balance;}public void deposit (int amount) {

balance += amount;}public void withdraw (int amount); //

abstractă}

Page 12: Structuri de Date în Java (III)vega.unitbv.ro/~galmeanu/java/suport/curs-3/doc/java-curs-3.pdfStructuri de Date în Java (III) Definirea unei clase (complet) Supraîncărcarea (overloading)

12

Derivare din clasă abstractăpublic class SavingsAccount extends BankAccount {

private int numberOfWithdrawals;public SavingsAccount () {

balance = 0;numberOfWithdrawals = 0;

}public void withdraw (int amount) { // trebuie definită

if (numberOfWithdrawals > 5) {throw new RuntimeException (“too many withdrawals”);

} else {balance -= amount;numberOfWithdrawals ++;

}}public void resetNumOfWithdrawals () {…}

}

Page 13: Structuri de Date în Java (III)vega.unitbv.ro/~galmeanu/java/suport/curs-3/doc/java-curs-3.pdfStructuri de Date în Java (III) Definirea unei clase (complet) Supraîncărcarea (overloading)

13

Polimorfism

● Obiecte de diferite tipuri folosesc aceleaşi metode (în fapt cu aceeaşi semnătură dar implementări diferite)

● Posibilitatea de a extinde sau suprascrie funcţionalitatea din clasa de bază (super – clasă)

● Java are grijă să discrearnă care din metodele suprascrise se vor rula efectiv

Page 14: Structuri de Date în Java (III)vega.unitbv.ro/~galmeanu/java/suport/curs-3/doc/java-curs-3.pdfStructuri de Date în Java (III) Definirea unei clase (complet) Supraîncărcarea (overloading)

14

Clasa Object

● Orice definiţie de clasă implicit extinde clasa java.lang.Object

● Clasa de bază java.lang.Object defineşte metode pe care le moştenesc toate clasele:

● clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait

Page 15: Structuri de Date în Java (III)vega.unitbv.ro/~galmeanu/java/suport/curs-3/doc/java-curs-3.pdfStructuri de Date în Java (III) Definirea unei clase (complet) Supraîncărcarea (overloading)

15

Suprascrierea (overriding)● Superclasă● dacă B extinde clasa A, spunem că A este

superclasa lui B● clasa B este subclasa lui A

● Dacă avem în clasa A o metodă cu semnătura:public void foo (int arg)● Atunci clasa B poate suprascrie metoda prin

definirea unei metode cu aceeaşi semnătură

● Nu confundaţi suprascrierea cu supraîncărcarea!

Page 16: Structuri de Date în Java (III)vega.unitbv.ro/~galmeanu/java/suport/curs-3/doc/java-curs-3.pdfStructuri de Date în Java (III) Definirea unei clase (complet) Supraîncărcarea (overloading)

16

Metoda toString● Implementată de clasa Object● Este apelată atunci când este nevoie de conversia acestui

tip de dată la tipul String● De regulă e necesară suprascrierea celei originale

class Account {public String toString () { return “account”; }

}

Account a = new Account ();System.out.println (a);System.out.println (a.toString ()); // valid, dar nenecesar

Page 17: Structuri de Date în Java (III)vega.unitbv.ro/~galmeanu/java/suport/curs-3/doc/java-curs-3.pdfStructuri de Date în Java (III) Definirea unei clase (complet) Supraîncărcarea (overloading)

17

Metoda clone● Clonarea se foloseşte pentru crearea unei copii bit cu bit identice

a obiectului

public Location implements Cloneable {public Object clone () {

Location answer;try {

answer = (Location)super.clone (); // typecast} catch (CloneNotSupportedException e) {

throw new RuntimeException ("class not cloneable"); } return answer;

}}

Page 18: Structuri de Date în Java (III)vega.unitbv.ro/~galmeanu/java/suport/curs-3/doc/java-curs-3.pdfStructuri de Date în Java (III) Definirea unei clase (complet) Supraîncărcarea (overloading)

18

Metoda equals

public boolean equals (Object o);

● Toate clasele moştenesc această metodă din clasa Object

● Implicit, ea realizează testul asupra egalităţii dintre referinţe, adică verifică dacă două referinţe “arată” spre acelaşi obiect din memorie

● Trebuie suprascrisă în cazul în care se doreşte verificarea egalităţii între două instanţe diferite ale clasei

Page 19: Structuri de Date în Java (III)vega.unitbv.ro/~galmeanu/java/suport/curs-3/doc/java-curs-3.pdfStructuri de Date în Java (III) Definirea unei clase (complet) Supraîncărcarea (overloading)

19

Implementarea implicită

CheckingAccount c1 = new CheckingAccount (100);CheckingAccount c2 = new CheckingAccount (100);

c1.equals (c1); // truec2.equals (c2); // truec1.equals (c2); // false

● Două obiecte de tip CheckingAccount ar trebui să fie egale dacă au aceeaşi sumă în ele!

Page 20: Structuri de Date în Java (III)vega.unitbv.ro/~galmeanu/java/suport/curs-3/doc/java-curs-3.pdfStructuri de Date în Java (III) Definirea unei clase (complet) Supraîncărcarea (overloading)

20

Suprascrierea metodei equals

public class CheckingAccount extends BankAccount {// …public boolean equals (Object o) {

if (o instanceof CheckingAccount) {CheckingAccount c = (CheckingAccount)o;return balance == c.balance;

} else{return false;

}}// …

}

Page 21: Structuri de Date în Java (III)vega.unitbv.ro/~galmeanu/java/suport/curs-3/doc/java-curs-3.pdfStructuri de Date în Java (III) Definirea unei clase (complet) Supraîncărcarea (overloading)

21

Efectul metodei suprascrise

CheckingAccount c1 = new CheckingAccount (100);CheckingAccount c2 = new CheckingAccount (100);

c1.equals (c1); // truec2.equals (c2); // truec1.equals (c2); // true

Page 22: Structuri de Date în Java (III)vega.unitbv.ro/~galmeanu/java/suport/curs-3/doc/java-curs-3.pdfStructuri de Date în Java (III) Definirea unei clase (complet) Supraîncărcarea (overloading)

22

Un alt fel mai general de a crea obiectele

Object o1 = new CheckingAccount (100);Object o2 = new CheckingAccount (100);

o1.equals (o1); // trueo2.equals (o2); // trueo1.equals (o2); // true

● Totuşi se cheamă metoda suprascrisă din clasa CheckingAccount chiar dacă referinţa o1 sau o2 este de tip Object

● Java “ştie” că de fapt în spate este un obiect de tip CheckingAccount

Page 23: Structuri de Date în Java (III)vega.unitbv.ro/~galmeanu/java/suport/curs-3/doc/java-curs-3.pdfStructuri de Date în Java (III) Definirea unei clase (complet) Supraîncărcarea (overloading)

23

Compile time vs. run-time

● Compile timeTipul de dată este stabilit la momentul scrierii

codului (la compilare)

● RuntimeCompilatorul nu cunoaşte ce fel de obiect se va

stoca de fapt într-o referinţă declarată generic de tip Object

Page 24: Structuri de Date în Java (III)vega.unitbv.ro/~galmeanu/java/suport/curs-3/doc/java-curs-3.pdfStructuri de Date în Java (III) Definirea unei clase (complet) Supraîncărcarea (overloading)

24

Method dispatching

● Java cheamă metoda pentru obiectul al cărui tip se determină la runtime

public abstract class BankAccount {// ...public void withdraw (int amount) { ... }// ...

}

● Clasele CheckingAccount şi SavingsAccount suprascriu metoda withdraw

Page 25: Structuri de Date în Java (III)vega.unitbv.ro/~galmeanu/java/suport/curs-3/doc/java-curs-3.pdfStructuri de Date în Java (III) Definirea unei clase (complet) Supraîncărcarea (overloading)

25

Exemplu: BankAccount

BankAccount b1 = new CheckingAccount (10);BankAccount b2 = new SavingsAccount (10);

b1.withdraw(5);// cheamă CheckingAccount.withdraw(int)

b2.withdraw(5);// cheamă SavingsAccount.withdraw(int)

Page 26: Structuri de Date în Java (III)vega.unitbv.ro/~galmeanu/java/suport/curs-3/doc/java-curs-3.pdfStructuri de Date în Java (III) Definirea unei clase (complet) Supraîncărcarea (overloading)

26

Apel de metodă cu tip generic

public boolean deleteAccount (BankAccount accnt) {// ...

}

BankAccount c = new CheckingAccount (20);// ...manager.deleteAccount (c);

● Metoda se poate apela cu obiecte de tipul SavingsAccount sau CheckingAccount, compilatorul nu are de unde să ştie asta

Page 27: Structuri de Date în Java (III)vega.unitbv.ro/~galmeanu/java/suport/curs-3/doc/java-curs-3.pdfStructuri de Date în Java (III) Definirea unei clase (complet) Supraîncărcarea (overloading)

27

Avantajele folosirii tipurilor generice

● Se poate schimba implementarea mai târziu (sau se scrie altă implementare)

● Nu trebuie schimbat nimic în codul care foloseşte tipul generic

● Se pot defini componente de tip plug-in pentru care specificăm doar metodele interfeţei, se poate ulterior crea orice implementare a acesteia

Page 28: Structuri de Date în Java (III)vega.unitbv.ro/~galmeanu/java/suport/curs-3/doc/java-curs-3.pdfStructuri de Date în Java (III) Definirea unei clase (complet) Supraîncărcarea (overloading)

28

Moştenire vs. compoziţie

● Moştenirea● se foloseşte când clasa derivată specializează clasa de

bază, păstrînd unele din metodele originale● avantajul e că nu trebuie să scriem prea mult cod în noua

clasă pentru că “vine de-a gata” funcţionalitatea existentă deja

● Compoziţia● conţine o clasă, procedeu folosit când clasa defineşte noi

comportamente bazîndu-se pe mai multe clase

Page 29: Structuri de Date în Java (III)vega.unitbv.ro/~galmeanu/java/suport/curs-3/doc/java-curs-3.pdfStructuri de Date în Java (III) Definirea unei clase (complet) Supraîncărcarea (overloading)

29

Exemplu de moştenireclass Rectangle {

public int width, height; public Rectangle (int width, int height) {

this.width = width; this.height = height;

}public int circumference () { return (width + height) * 2; }

}class Square extends Rectangle {

Square (int x) {super (x, x); // cheamă constructorul super-clasei

}}

Square square = new Square (3); circumference (sq); // întoarce 12, ok

Page 30: Structuri de Date în Java (III)vega.unitbv.ro/~galmeanu/java/suport/curs-3/doc/java-curs-3.pdfStructuri de Date în Java (III) Definirea unei clase (complet) Supraîncărcarea (overloading)

30

Exemplu de compoziţie

class Geometric {public Rectangle r; // noile obiecte sunt datepublic Square s; // ca variabile membrepublic Geometric (int width, int height) {

r = new Rectangle (width, height);s = new Square (width);

}public int circumference () {

return s.circumference () + r.circumference ();}

Page 31: Structuri de Date în Java (III)vega.unitbv.ro/~galmeanu/java/suport/curs-3/doc/java-curs-3.pdfStructuri de Date în Java (III) Definirea unei clase (complet) Supraîncărcarea (overloading)

31

Excepţii● Scop: ajută programatorul în a raporta şi trata erorile● Ce se întâmplă la aruncarea unei excepţii?● firul normal de execuţie al programului se întrerupe● se caută un handler de tratare:try {

// acţiuni care pot arunca excepţia} catch (<tip excepţie A> name) {

// tratează excepţia A} catch (<tip excepţie B> name) {

// tratează excepţia B} finally {

// acţiuni care se execută după ce s-a tratat// oricare din excepţii

}

Page 32: Structuri de Date în Java (III)vega.unitbv.ro/~galmeanu/java/suport/curs-3/doc/java-curs-3.pdfStructuri de Date în Java (III) Definirea unei clase (complet) Supraîncărcarea (overloading)

32

Prinderea excepţieiclass Editor {

public boolean openFile (String filename ) {try {

boolean fileOpen = true;File f = new File (filename);// alte activităţi cu freturn true;

} catch (FileNotFoundException e) { e.printStackTrace ();return false;

} finally { fileOpen = false;

}System.out.println (“bar“);

}}

Page 33: Structuri de Date în Java (III)vega.unitbv.ro/~galmeanu/java/suport/curs-3/doc/java-curs-3.pdfStructuri de Date în Java (III) Definirea unei clase (complet) Supraîncărcarea (overloading)

33

Aruncarea excepţiei

public class File {public File (String filename) throws

FileNotFoundException {// …if ( can’t find file ) {

throw new FileNotFoundException (); }

}}

// declaraţia throws instruieşte compilatorul să asigure că// programul ce foloseşte clasa face şi tratarea excepţiei

Page 34: Structuri de Date în Java (III)vega.unitbv.ro/~galmeanu/java/suport/curs-3/doc/java-curs-3.pdfStructuri de Date în Java (III) Definirea unei clase (complet) Supraîncărcarea (overloading)

34

Clase conţinute (nested- sau inner- classes)

class EnclosingClass {// ...class NestedClass {

// ...}// ...

}

Page 35: Structuri de Date în Java (III)vega.unitbv.ro/~galmeanu/java/suport/curs-3/doc/java-curs-3.pdfStructuri de Date în Java (III) Definirea unei clase (complet) Supraîncărcarea (overloading)

35

Nested classes (încuibărite)

● Au acces la toţi membrii clasei ce o conţine, chiar dacă aceştia sunt private

● Pot fi declarate static (sau final, abstract)● Clasele nested ne-statice se numesc inner-classes

class EnclosingClass {static class StaticNestedClass { ... }class InnerClass { ... }

}

Page 36: Structuri de Date în Java (III)vega.unitbv.ro/~galmeanu/java/suport/curs-3/doc/java-curs-3.pdfStructuri de Date în Java (III) Definirea unei clase (complet) Supraîncărcarea (overloading)

36

Inner classes

● Sunt asociate cu o instanţă a clasei● Nu pot declara membri statici● Pot fi instanţiate doar în contextul clasei care o

conţine

Outer class Inner class

Page 37: Structuri de Date în Java (III)vega.unitbv.ro/~galmeanu/java/suport/curs-3/doc/java-curs-3.pdfStructuri de Date în Java (III) Definirea unei clase (complet) Supraîncărcarea (overloading)

37

Clase inner locale● Presupunem cunoscută declaraţia interfeţei Iterator

public class Stack {private ArrayList items; public Iterator iterator () {

private class StackIterator implements Iterator {int currentItem = items.size() - 1;public boolean hasNext () { ... }public ArrayList<Object> next() { ... }public void remove () { ... }

}return new StackIterator ();

}// clasa inner se poate declara şi aici

}

Page 38: Structuri de Date în Java (III)vega.unitbv.ro/~galmeanu/java/suport/curs-3/doc/java-curs-3.pdfStructuri de Date în Java (III) Definirea unei clase (complet) Supraîncărcarea (overloading)

38

Clase inner anonime● Se doreşte ca rezultatul întors să fie un obiect cu tip clasă ce

implementează interfaţa Iterator● Lipseşte numele clasei!

public class Stack {private ArrayList items;public Iterator iterator () {

return new Iterator() {int currentItem = items.size() - 1;public boolean hasNext() { ... }public ArrayList<Object> next () { ... }public void remove () { ... }

};}

}