Sunteți pe pagina 1din 17

Curs: Core Java Programing

Module: Programarea orientată pe obiecte în Java


Unitate: Clase abstracte şi interfeţe

Povestea despre clase o continuăm cu clasele abstracte şi cu


interfeţele.

Clasele abstracte

Uneori este recomandată crearea unei superclase, în aşa fel încât


aceasta să reprezinte doar baza pentru crearea altor clase. Această
clasă se va folosi ca un şablon, respectiv ca o linie directoare a ceea ce
trebuie să conţină clasele care vor moşteni această clasă. În Java,
astfel de clase se numesc clase abstracte. Ceea ce este caracteristic
pentru acest tip de clase este că ele nu se pot instanţia. Acest lucru
este şi logic, tocmai din cauza motivului menţionat la început: aceste
clase nu sunt prevăzute pentru crearea obiectelor, ci pentru crearea
unui anumit şablon destinat creării altor clase.

Întregul exemplu abordat în cadrul lecţiei despre moştenire poate fi


realizat şi în aşa fel încât clasa Person să fie declarată ca una
abstractă.

abstract class Person {


public String firstName;
public String lastName;
}

Observaţi că pentru definirea clasei Person ca una abstractă, am folosit


cuvântul cheie abstract. Dacă declarăm clasa Person în modul
prezentat în codul de mai sus, nu vom observa nicio diferenţă în
folosirea altor clase care o moştenesc, aceasta până când nu vom
încerca să instanţiem această clasă. Dacă am fi încercat să o
instanţiem, s-ar fi produs o eroare, deoarece clasa abstractă, după cum
am spus deja, nu se poate instanţia.

© Copyright Link group 1 / 17


Curs: Core Java Programing
Module: Programarea orientată pe obiecte în Java
Unitate: Clase abstracte şi interfeţe

Imaginea 18.1 Încercarea de instanţiere a clasei abstracte

Faptul că clasa este abstractă nu înseamnă nimic altceva decât că ea


nu poate fi instanţiată. Clasa abstractă poate fi doar moştenită. În
acelaşi mod, putem declara şi metoda ca abstractă. Atunci metoda nu
va conţine corpul, ci doar semnătura.

abstract class Person {

public String firstName;


public String lastName;

public abstract void show();

Când în clasa părinte apare o astfel de metodă, clasa care moşteneşte


această clasă este obligată să implementeze o astfel de metodă.

© Copyright Link group 2 / 17


Curs: Core Java Programing
Module: Programarea orientată pe obiecte în Java
Unitate: Clase abstracte şi interfeţe

Imaginea 18.2 Obligaţia clasei de a implementa metode abstracte

Mediul de dezvoltare ne va semnala unde este problema. Ceea ce


trebuie să facem este să implementăm metoda show.

public class Student extends Person {

public String indexNumber;

@Override
public void show() {

System.out.println("Student: " + firstName + " " + lastName);

}
}

De asemenea, această metodă se poate implementa şi în mod


automat, respectiv mediul de dezvoltare poate face aceasta pentru
noi. Este suficient să alegem iconiţa hint din marginea stângă, iar apoi
opţiunea Implement all abstract methods.

© Copyright Link group 3 / 17


Curs: Core Java Programing
Module: Programarea orientată pe obiecte în Java
Unitate: Clase abstracte şi interfeţe

Imaginea 18.3 Implementare automată a tuturor metodelor abstracte


în NetBeans

În acest mod vor fi implementate toate metodele declarate ca


abstracte în clasa părinte. Ceea ce trebuie să faceţi este să adăugaţi
funcţionalităţi în corpurile metodelor. Observăm că mediul a adăugat
pentru noi adnotarea @Override. Despre aceasta am scris deja în lecţia
privind polimorfismul. Introducerea acestei adnotări nu este necesară,
adică editorul nu va semnala o eroare dacă omitem să facem acest
lucru. Totuşi, adăugarea adnotării @Override este considerată o
practică bună pentru claritatea şi uşurinţa de mentenanţă a codului. De
asemenea, dacă adăugaţi această adnotare, editorul mediului de
dezvoltare va şti că aveţi intenţia de a suprascrie metoda din clasa
părinte şi vă va ajuta dacă, de exemplu, scrieţi greşit denumirea
metodei.

De asemenea, în imaginea de mai sus, în care vedem notificarea


mediului cu privire la clasa Student, care ne spune că este necesară
implementarea unei metode care nu este implementată, mesajul afişat
ar fi arătat astfel: „Student is not abstract and does not override
abstract method show() in Person“. Aceasta însemnă că, în cazul în
care definim clasa Student ca una abstractă, aceasta nu va fi obligată
să implementeze metodele abstracte din clasa părinte. Această
metodă va trebui să fie implementată de prima clasă din lanţul de
moştenire, care nu este abstractă.

abstract class Student extends Person {


public String indexNumber;

© Copyright Link group 4 / 17


Curs: Core Java Programing
Module: Programarea orientată pe obiecte în Java
Unitate: Clase abstracte şi interfeţe

}
public class Freshman extends Student {
@Override
public void show() {
//logic goes here
}
}

Interfeţele

Pe lângă metode abstracte, care pot conţine doar semnătura, clasele


abstracte mai pot conţine şi metode, şi atribute “clasice”. Am spus
deja că clasele abstracte reprezintă baza pentru crearea altor clase. În
limbajul Java există o formă şi mai abstractă, care conţine în general
doar semnături ale metodelor. Această formă se numeşte interfaţă.

Interfaţa conţine, în general, doar semnăturile metodelor, iar atunci


când interfaţa se implementează în clasă, toate metodele specificate în
ea trebuie să fie implementate în clasa respectivă.

Să ne imaginăm situaţia în care trebuie să creăm o clasă Calc care se


va folosi pentru reprezentarea logicii unui calculator de buzunar. După
ce am creat o clasă Calc goală, putem să creăm şi prima interfaţă.

Noi vrem să impunem clasei Calc create să conţină metode pentru


calcularea operaţiilor aritmetice. De aceea vom crea o interfaţă simplă
Operations care va conţine metoda add. Singura diferenţă în definirea
unei interfeţe comparativ cu definirea unei clase este că în loc de
cuvântul cheie class, interfaţa foloseşte cuvântul cheie interface:

public interface Operations {


}

© Copyright Link group 5 / 17


Curs: Core Java Programing
Module: Programarea orientată pe obiecte în Java
Unitate: Clase abstracte şi interfeţe

Din mediul de dezvoltare NetBeans, interfaţa se creează la fel ca şi


clasa, numai că, în loc de opţiunea Java Class, alegem opţiunea Java
Interface.

Imaginea 18.4 Crearea interfeţei

După introducerea metodei add, interfaţa va arăta astfel:

public interface Operations {


public double add();
}

Pentru ca interfaţa să fie implementată în clasă, este necesar să


folosim cuvântul cheie implements. Implementarea va arăta astfel:

public class Calc implements Operations {


public double add() { }
}

© Copyright Link group 6 / 17


Curs: Core Java Programing
Module: Programarea orientată pe obiecte în Java
Unitate: Clase abstracte şi interfeţe

Spre deosebire de moştenirea claselor, moştenirea interfeţelor nu


implică doar o singură interfaţă per clasă, ci o clasă poate moşteni un
număr nelimitat de interfeţe. Vom crea acum încă o interfaţă
Operands, care va conţine metoda setOperands:

public interface Operands {


public void setOperands(double a, double b);
}

Pentru ca clasa să implementeze mai multe interfeţe, trebuie să le


adăugăm una după alta, cu virgulă între denumirile interfeţelor.

public class Calc implements Operations, Operands {


public double add() {
//logic goes here
}
public void setOperands() {
//logic goes here
}
}

Exerciţii

Exerciţiul nr. 1

Pentru aplicaţia unui restaurant de fast food, trebuie creată clasa


abstractă Produs. Această clasă conţine proprietăţi publice: int
tipProdus, String nume şi double preţul de bază, precum şi un şir de
stringuri adaosuri, care poate conţine cel mult 10 adaosuri. De
asemenea, această clasă conţine şi metoda introducere adaos care
introduce adaosul pentru produs (salată, condimente etc.) şi metoda

© Copyright Link group 7 / 17


Curs: Core Java Programing
Module: Programarea orientată pe obiecte în Java
Unitate: Clase abstracte şi interfeţe

toateAdaosurile, care returnează toate adaosurile sub formă de string.


Clasa trebuie să aibă şi o metodă abstractă, calcularePreţ, care va
calcula preţul pe baza tipului de produs. În timpul calculării preţului
produsului, trebuie să aveţi grijă la taxa pentru pizza de 10%, în timp
ce taxa pentru sendvişuri este de 15%.

Clasa trebuie să posede şi metoda suprascrisă toString care va afişa


datele despre produs în următoarea formă:

Produs: pizza, preţ: 25,45, adaosuri: roşii, muştar, maioneză.

Trebuie create clasele Pizza şi Sendviş care moştenesc clasa Produs şi


trebuie creat codul pentru crearea unei instanţe a claselor Pizza şi
Sendviş în metoda Main. Clasele Pizza şi Sendviş necesită în
constructor numele şi preţul produsului.

Rezolvare:

//Clasa Produs
public abstract class Product {
//Declararea variabilelor
public int type;
public String name;
public double price;
public String[] additions;
public abstract double countPrice();
//Suprascrierea metodei toString
@Override
public String toString() {
//Fiindcă se execută concatenarea stringului, cea mai eficientă variantă este folosirea clasei S
tringBuilder
StringBuilder output = new StringBuilder();
//Se adaugă date despre produs. this.name va fi atribuită constructorului.
//De asemenea, şi preţul va fi atribuit în constructor, însă acesta nu se scrie direct,
//ci se procesează prim metoda calculare preţ
//(această metodă va fi scrisă mai târziu la nivelul clasei copil,
//deoarece fiecare clasă copil are propria cotă de impozitare)
output.append("Produs: ");

© Copyright Link group 8 / 17


Curs: Core Java Programing
Module: Programarea orientată pe obiecte în Java
Unitate: Clase abstracte şi interfeţe

output.append(this.name + ", ");


output.append("preţ: " + countPrice() + ", ");
output.append("adaosuri: " + allAdditions());
return output.toString();
}
//metoda pentru afişarea tuturor adaosurilor
public String allAdditions()
{
//şi în acest caz va exista probabil concatenarea stringurilor, aşadar se foloseşte StringBuilder
StringBuilder output = new StringBuilder();
//se trece prin lista de adaosuri, folosind bucla for. Atâta timp cât membrul listei nu este null,
//variabilei ieşire i se adaugă membrul listei cu un semn adăugat,
for(int i=0;i<this.additions.length;i++)
if(this.additions[i]!=null)
output.append(this.additions[i] + ", ");
//la sfârşit trebuie eliminată ultima virgulă şi dacă nu există adaosuri, scrieţi mesajul: fără ad
aosuri
if(!output.toString().equals(""))
{
if(output.toString().trim().endsWith(","))
output.replace(output.length()-2, output.length(), "");
}
else
output.append("fără adaosuri");
return output.toString();
}
public void addition(String addition) {
//se trece prin lista de adaosuri, până la primul membru inexistent (null).
//În membrul inexistent se introduce o valoare şi se întrerupe bucla
for(int i=0;i<this.additions.length;i++)
if(this.additions[i]==null)
{
this.additions[i]=addition;
break;
}
}
}
//Clasa Pizza moşteneşte clasa Produs

© Copyright Link group 9 / 17


Curs: Core Java Programing
Module: Programarea orientată pe obiecte în Java
Unitate: Clase abstracte şi interfeţe

public class Pizza extends Product {


public Pizza(String name, double price)
{
//Se atribuie parametrii prin constructor
this.additions = new String[10];
this.name = name;
this.price = price;
}
public double countPrice() {
//Se calculează preţul produsului cu taxa de 10%
return this.price + this.price*0.1;
}
}
//Clasa Sendviş moşteneşte clasa Produs
public class Sandwich extends Product {
public Sandwich(String name, double price)
{
//Se atribuie parametrii prin constructor
this.additions = new String[10];
this.name = name;
this.price = price;
}
public double countPrice() {
//Se calculează preţul produsului cu taxa de 15%
return this.price + this.price*0.15;
}
}
//Programul principal
public class Main {
public static void main(String[] args) {
//Instanţierea clasei Pizza
Pizza p = new Pizza("Capriciossa",25);
//Adăugare adaosuri
p.addition("roşii");
p.addition("smântână");
//Instanţierea clasei Sendviş
Sandwich s = new Sandwich("Sendviş cu şuncă", 35);
//Adăugare adaosuri

© Copyright Link group 10 / 17


Curs: Core Java Programing
Module: Programarea orientată pe obiecte în Java
Unitate: Clase abstracte şi interfeţe

p.addition("castravete");
p.addition("ceapă");
p.addition("roşii");
//Afişarea claselor Pizza şi Sendviş
System.out.println(p);
System.out.println(s);
}
}

Soluţie simplificată:

Clasa Product

public abstract class Product {

public int type;


public String name;
public double price;
public String[] additions;

public abstract double countPrice();

@Override
public String toString() {

return "Produs: " + this.name + ", " + "preţ: " + countPrice() + ", " + "adaosuri: " + allAdditions
();
}

public String allAdditions() {

String output = "";

for (int i = 0; i < this.additions.length; i++) {


if (this.additions[i] != null) {

© Copyright Link group 11 / 17


Curs: Core Java Programing
Module: Programarea orientată pe obiecte în Java
Unitate: Clase abstracte şi interfeţe

output += this.additions[i] + ", ";


}
}

if (output.equals("")) {
output += ("fără adaosuri");
}

return output;
}

public void addition(String addition) {

for (int i = 0; i < this.additions.length; i++) {


if (this.additions[i] == null) {
this.additions[i] = addition;
break;
}
}
}

Clasa Sendviş:

public class Sandwich extends Product {

public Sandwich(String name, double price) {

this.additions = new String[10];


this.name = name;
this.price = price;
}

© Copyright Link group 12 / 17


Curs: Core Java Programing
Module: Programarea orientată pe obiecte în Java
Unitate: Clase abstracte şi interfeţe

public double countPrice() {

return this.price + this.price * 0.15;


}

Clasa Pizza:

public class Pizza extends Product {

public Pizza(String name, double price) {

this.additions = new String[10];


this.name = name;
this.price = price;
}

public double countPrice() {

return this.price + this.price * 0.1;


}

Clasa principală:

public static void main(String[] args) {

Pizza p = new Pizza("Capricciosa", 25);

Sandwich s = new Sandwich("Sendviş cu şuncă", 35);

© Copyright Link group 13 / 17


Curs: Core Java Programing
Module: Programarea orientată pe obiecte în Java
Unitate: Clase abstracte şi interfeţe

s.addition("castravete");
s.addition("ceapă");
s.addition("roşii");

System.out.println(p);
System.out.println(s);

Exerciţiul nr. 2

Trebuie creată clasa abstractă Quad care va conţine 3 câmpuri


(x, y şi a) şi o metodă abstractă (Setxya).

Trebuie creată interfaţa IGeom care va conţine semnăturile


metodelor pentru calcularea ariei şi a perimetrului.

Trebuie creată clasă Square care moşteneşte clasa Quad şi


implementează interfaţa IGeom.

Trebuie creată o instanţă a clasei Square în programul


principal.

Rezolvare:

interface IGeom {
int area();
int perimeter();
}

abstract class Quad {


public int x;

© Copyright Link group 14 / 17


Curs: Core Java Programing
Module: Programarea orientată pe obiecte în Java
Unitate: Clase abstracte şi interfeţe

public int y;
public int a;
public abstract void setxya(int x, int y, int a);
}

class Square extends Quad implements IGeom {


@Override
public int area() {
return a*a;
}

@Override
public int perimeter() {
return 4*this.a;
}

@Override
public void setxya(int x, int y, int a) {
this.x = x;
this.y = y;
this.a = a;
}
}
public class Main {
public static void main(String[] args) {
Square s = new Square();
s.setxya(100, 100, 5);
System.out.println(s.area());
System.out.println(s.perimeter());
}
}

Exerciţiul nr. 3

Sunt necesare două interfeţe pentru aplicaţia calculator (de


buzunar): Operands şi Operations. Operands conţine semnătura

© Copyright Link group 15 / 17


Curs: Core Java Programing
Module: Programarea orientată pe obiecte în Java
Unitate: Clase abstracte şi interfeţe

metodei setOperands care pune operanzii la valorile iniţiale, în


timp ce Operations conţine semnături ale metodelor cu operaţii
(sunt suficente doar două).

Trebuie creată clasa Calculator care va implementa interfeţele


Operands şi Operations.

Trebuie instanţiată clasa Calculator în aplicaţia principală şi


trebuie activate metodele sale Adunare şi Scădere.

Rezolvare:

public interface Operands {


public void setOperands(double a, double b);
}

public interface Operations {


public double add();
public double sub();
}

public class Calculator implements Operations, Operands {


public double a;
public double b;
public double add() { return a+b; }
public double sub() { return a-b; }
public void setOperands(double a, double b) {
this.a = a;
this.b = b;
}
}

public class Main {


public static void main(String[] args) {
Calculator c = new Calculator();

© Copyright Link group 16 / 17


Curs: Core Java Programing
Module: Programarea orientată pe obiecte în Java
Unitate: Clase abstracte şi interfeţe

c.setOperands(2, 3);
System.out.println(c.add());
System.out.println(c.sub());
}
}

© Copyright Link group 17 / 17

Powered by TCPDF (www.tcpdf.org)

S-ar putea să vă placă și