Sunteți pe pagina 1din 18

Moștenire multiplă.

Interfețe
profesor Dobrovolischii Olga
Interfețele

Definiție: Interfața este o colecție de metode și date membre publice.


Contract, protocol de comunicare
Interfețele descriu un model, contract
Clasele implementează modelul, aderă la contract

Cum se definește o interfață?


Sintaxa:

De exemplu: interface Animal{


void maninca();
void doarme();
De ce se utilizează interfețele în Java?

3
Clasele vs Interfețe
Clasele sunt folosite pentru a reprezenta ceva care are atribute (variabile, câmpuri) şi
capabilități/responsabilități (metode, funcționalități).
Interfețele descriu doar capabilități.
Asemănări
O interfață poate conține orice număr de metode
O interfață este scrisă într-un fișier cu extensia .java și numele fișierului coincide cu numele
interfeței
Codul pe biți al unei intefețe apare într-un fișier cu extensia .class
Interfețele sunt grupate în pachte.
Deosebiri
O interfață nu poate fi instanțiată
O interfață nu conține constructori
O interfață nu poate conține cîmpuri de instanță. singurele cîmpuri care pot apărea într-o
interfață trebuie declarate atît static cît și final.
O interfață nu este moștenită de o clasă , ea este implementată de aceasta.
O interfață poate moșteni mai multe interfețe.
Rețineți:

Numele interfeței nu coincide cu numele altei clase sau interfețe din același pachet.
Dacă declarația unei interfețe conține clauza extends atunci interfața va moșteni toate metodele
și constantele interfețelor enumerate în <ListaInterfete>, care se numesc superinterfețe.
Corpul unei metode într-o interfață este ;.
Toți membrii interfeței sunt considerați implicit publici, dar dacă modificatorul public este
specificat atunci sunt accesibili și în afara pachetului.
Deoarece variabilele unei interfețe sunt considerate constante acestea trebuie să fie
inițializate astfel se va produce eroare de compilare. Exemplu: int x;(eroare) int x=10 ;(corect)
Metode cu același nume dar tip de return diferit nu pot fi folosite în interfețe
Variabilele unei interfețe sunt considerate implicit public, static și final. Chiar dacă veți omite
aceste cuvinte rezervate vor fi adăugate în mod automat de compilatorul Java la faza de
compilare , în fișierul *.class.
Rețineți:

8. E posibil ca o clasă să folosească variabilele cu același nume dintr-o altă interfață, în


acest caz la accesarea acestora trebuie de respectat sintaxa:
numeInterfață.numeVariabilă

9. La declararea unei metode nu este permisă apariția tuturor modificatorilor de acces,


doar public și abstract.

10. Dacă o clasă implementează 2 interfețe ce au metode cu aceleași nume este deajuns
să implementăm o singură metodă.
Cum o clasă implementează o interfață?

Pentru ca o clasă să implementeze o interfață trebuie să respecte sintaxa:


class numeClasa implements Interfata1,...,InterfataN
{ ...
}

De exemplu:
class Cal implements Animal{
void maninca(){...}
void doarme(){...}
Observații:

O clasă poate implementa orice număr de interfețe


O clasă ce implementează o interfață trebuie obligatoriu să conțină cod pentru toate
metodele interfeței , din acest motiv o interfață implementată într-o clasă nu trebuie
modificată , dacă modificăm interfața obligatoriu modificăm și codul sursă al clasei ce o
implementează.
Clasa ce implementează o interfață poate avea și metode specifice ei , nu doar metodele
interfeței:

De exemplu:
class Cal implements Animal{
void manica(){System.out.println(“Calul maninca”);}
void doarme(){System.out.println(“Calul doarme”);}
void participa(){System.out.println(“Participa la intreceri”);}
}
O interfață poate extinde o altă interfață, dar nu o poate implementa.
Exemplu:
public interface Poligon {
void getAria(int... laturi);

public class Dreptunghi implements Poligon {


public void getAria(int... laturi) {
if (laturi.length == 2)
System.out.println("Aria dreptunghiului este " + (laturi[0] * laturi[1]));
class Patrat implements Poligon {
public void getAria(int... laturi) {
if (laturi.length == 1)
System.out.println("Aria patratului este " + (Math.pow(laturi[0], 2)));
}}

class Main {
public static void main(String[] args) {
Dreptunghi r1 = new Dreptunghi();
r1.getAria(5, 6);
Patrat p1 = new Patrat();
p1.getAria(5);
}

}
Cum simulăm moștenirea multiplă folosind Interfețe?

Atunci cînd o altă clasă implementează mai multe interfețe , sau o interfață extinde mai
multe interfețe spunem că simulăm moștenirea multiplă.

interface interface

interface
Exemplu 1;
public interface Masina {
int viteza = 90;
public void distanta();
}
public interface Autobus {
int distanta = 100;
public void viteza();}

public class Vehicul implements Masina, Autobus {


public void distanta() {
int distanta = viteza * 100;
System.out.println("Distanta parcursa este " + distanta);
}

public void viteza() {


int viteza = distanta / 100;
System.out.println("Viteza este " + viteza);
}

static class DemoVehicule {


public static void main(String[] args) {
System.out.println("Vehicul");
Vehicul v1 = new Vehicul();
v1.distanta();
v1.viteza();}}}
Exemplu 2;
public interface Interfata_1 {
public void metoda_1();

}
public interface Interfata_2 extends Interfata_1 {
public void metoda_2();

}
public class DemoInterfete implements Interfata_2 {
public void metoda_1() {
System.out.println("Aici metoda 1");
}

public void metoda_2() {


System.out.println("Aici metoda 2");
}

public static void main(String args[]) {


DemoInterfete obj = new DemoInterfete();
obj.metoda_2();
}}
Notă; Interfețele nu pot fi instanțiate însă putem crea variabile referință de tip interfață. De
exemplu , dacă în exemplul 2 , în metoda main() vom folosi construcția:

Interfata_2 obj = new DemoInterfete();


obj.metoda_2();

Aceasta este validă , iar programul va afișa același rezultat. Vor fi apelate pentru obiectul
obj acele metode din Interfata_2 care au impementare în clasa dată.

Variabilele referință de tip interfață se folosesc doar urmate de instanțierea clasei ce


implementează interfața la care face referință variabila.
Metode default și statice în Interfețe

Începînd cu versiunea Java 8 este permis ca în interfețe să fie definite metode statice si/sau
default după sintaxa:

public interface InterfataMea {


void metodaClasica();

default void metodaDefault() {


System.out.println("metoda default");
}
static void metodaStatica() {
System.out.println("metoda statica");
}}
Reguli de reținut:

Atît metodele default cît și metodele statice în interfață trebuie să conțină corp.

Metodele statice:

a. pot fi accesate direct , respectînd sintaxa: InterfataMea.metodaStatica()

b. aparțin în exclusivitate interfețelor, nu pot fi accesate de instanțele claselor care vor


implementa interfața.

c.clasele care vor implementa interfața nu vor putea supradefini așa tip de metodă

d.clasele care vor implementa interfața vor avea posibilitatea să conțină metodă cu același
nume ca și metoda statică.
Reguli de reținut:

3. Metodele default
nu pot fi accesate direct
clasele care vor implementa interfața are dreptul sa supradefinească așa tip de metodă
permit modificarea interfețelor fără a afecta clasele care deja au implementat interfața
atunci cînd extinzi o interfață de către altă interfață care are o metodă default poți face una
din următoarele acțiuni:
să nu o menționezi, ceea ce înseamnă că o moștenești așa cum e de la interfață
să o redeclari , ceea ce o face de tip abstract , iar clasele care vor implementa interfața , vor
adăuga o altă implementare a acestei metode
să o redefinești, ceea ce o suprascrie pe cea originală, cu o implementare default diferită
Avantajele acestor tip de metode în cadrul interfețelor sunt următoarele:
metode statice: există dreptul de a nu defini o clasă separată pentru o metodă utilitară
metode default: există posibilitatea de a defini o funcționalitate comună pentru toate clasele
care vor implementa interfața.
Exemplu:
public interface Vehicul { public class Masina implements Vehicul { public class TestMasina {
String getBrand(); private String brand;
public static void main(String[]
String speedUp(); Masina(String nume) { args) {
brand = nume; Vehicul car = new
String slowDown(); } Masina("BMW");

default String turnAlarmOn() { public String getBrand() { System.out.println(car.getBrand());


return "Alarma conectata"; return brand;
} } System.out.println(car.speedUp());

default String turnAlarmOff() { public String speedUp() { System.out.println(car.slowDown());


return "Alarma return ("Masina
deconectata"; accelereaza"); System.out.println(car.turnAlarmOn());
} }
System.out.println(car.turnAlarmOff());
} public String slowDown() {
return "Masina incetineste"; }
}
}
}
Exemplu:
public interface Drawable { public class Rectangle implements public class TestInterfaceStatic {
void draw(); Drawable { public static void main(String args[])
public void draw() { {
static int cube(int x) { System.out.println("drawing rectangle"); Drawable d = new Rectangle();
return x * x * x; } d.draw();
} }
} System.out.println(Drawable.cube(
3));
}
}