Објектно орјентисано
програмирање
Владимир Филиповић
vladaf@matf.bg.ac.rs
Александар Картељ
kartelj@matf.bg.ac.rs
интерфејси
Владимир Филиповић
vladaf@matf.bg.ac.rs
Александар Картељ
kartelj@matf.bg.ac.rs
Математички факултет (^) {vladafvladaf@matf.bg.ac.,kartelj}@matf.bg.ac.rs rs 3 / 23
У развоју софтвера је често важно да се различите групе
програмера договоре око „уговора“ о интеракцији софтвера.
Свака од тих група треба да буде у могућности да напише
свој део кода, а да при томе нема информације како је писан
код друге стране.
У језику Јава, интерфејс је референтни тип, сличан класи, али
може садржати само константе и потписе метода.
Интерфејс не може да садржи тела метода (изузетак су
подразумевани методи, почев од Јава 8).
Није могуће директно правити примерак интерфејса:
он само може да буде имплементиран од стране класе
или наслеђен од стране другог интерфејса
Интерфејси
Математички факултет (^) {vladafvladaf@matf.bg.ac.,kartelj}@matf.bg.ac.rs rs 8 / 23
Интерфејси (као апстрактне класе и методи) обезбеђују
шаблоне за неко понашање, а које ће друге класе користити.
Преко интерфејса уводи се неки вид ограниченог вишеструког
наслеђивања.
Интерфејс обезбеђује апстрактно понашање које се додаје
било којој класи, а које није обезбеђено преко њених надкласа.
Они представљају неку врсту протокола за комуникацију
између класа, тј. дефинишу шаблоне за понашање класа.
Интерфејси (2)
Математички факултет (^) {vladafvladaf@matf.bg.ac.,kartelj}@matf.bg.ac.rs rs 9 / 23
- Интерфејс се понаша свуда као класа, али не може имати
инстанце (не може се на њега применити оператор new).
- Интерфејс садржи апстрактне методе (што се не мора
посебно нагласити јер се подразумева) и константе.
- Дакле, интерфејс не може садржавати променљиве.
- Нови интерфејс се креира са: public interface MojInterfejs { ……. }
Интерфејси (3)
Математички факултет (^) {vladafvladaf@matf.bg.ac.,kartelj}@matf.bg.ac.rs rs 10 / 23
- Код интерфејса нема хијерархијске организације.
- Како би нагласили да један интерфејс наслеђује више других,
иза кључне речи extends наводимо све интерфејсе које овај
наслеђује.
public interface DrugiInterfejs extends Prvi , Primarni {
...// svi metodi su public i abstract
...//sve promenljive su: public, static i final
}
- Интерфејси се, као и класе, смештају у пакете.
- Ако се за методе и променљиве у интерфејсу не нагласи да су
abstract, public и final, подразумеваће се да је тако.
Интерфејси (4)
Математички факултет (^) {vladafvladaf@matf.bg.ac.,kartelj}@matf.bg.ac.rs rs 11 / 23
- Дефинисани интерфејси се имплементирају од стране Јава
класа.
- Можемо користити већ раније дефинисане интерфејсе (који
већ постоје у Јава-библиотеци) или направити своје.
- Када класа имплементира интерфејс, тада сe морају
имплементирати сви методи интерфејса (не могу се бирати
само неки међу њима да се имплементирају, а неки да се
оставе неимплементираним).
class MojAplet extends java. applet. Applet implements Runnable { …… .. //implementacije svih metoda iz interfejsa Runnable }
Интерфејси (5)
Математички факултет (^) {vladafvladaf@matf.bg.ac.,kartelj}@matf.bg.ac.rs rs 12 / 23
- Kaдa сe интерфејс имплементира у некој класи, њена поткласа
наслеђује све методе и може их превазићи (предефинисати).
- Ако је у класи имплеметиран интерфејс, није неопходно да се реч
implements јави и у дефиницији поткласе.
Пример:
interface Radoznao { void pita (); void interesuje_se (); //… } class Naucnik implements Radoznao { String ime ; // … } class Istrazivac extends Naucnik { // Ovde se mogu koristiti metodi pita() i Interesuje_se() }
Интерфејси (6)
Математички факултет (^) {vladafvladaf@matf.bg.ac.,kartelj}@matf.bg.ac.rs rs 13 / 23
- Једна класа може имплементирати више интерфејса.
- На пример, може се писати:
public class Moja implements Prvi , Drugi , Treci {
// … }
- Овде се могу појавити иста имена метода (са истим потписом!) у
различитим интерфејсима.
- Тада се коришћењем кратког имена може имплементирати само
један од два таква метода (ако се редефинишу оба метода унутар
класе, неопходно је користити пуна имена).
Интерфејси (7)
Математички факултет (^) {vladafvladaf@matf.bg.ac.,kartelj}@matf.bg.ac.rs rs 14 / 23
- Могу се декларитати променљиве које ће бити типа интерфејс
(јер скоро свуда где користимо класе, можемо користити и
интерфејсе!)
- На пример, могуће је креирати објекат на следећи начин: Runnable trceci = new MojObjekat ();
- Од објекта trceci се очекује да извршава метод run() интерфејса
Runnable.
Интерфејси (8)
Математички факултет (^) {vladafvladaf@matf.bg.ac.,kartelj}@matf.bg.ac.rs rs 15 / 23
- Како се могу користити параметри у методима интерфејса
ако ће их имплементирати различите класе?
- Једна од могућности је да се параметри декларишу тако да
буду типа интерфејса.
public interface Radoznao {
void pita ( Radoznаo neko );
//...
}
public class Naucnik implements Radoznao {
public pita ( Radoznao neko ){
Naucnik pravi = ( Naucnik ) neko ;
// ...
}
}
Интерфејси ( 9 )
Математички факултет (^) {vladafvladaf@matf.bg.ac.,kartelj}@matf.bg.ac.rs rs 16 / 23
- Обично испоручилац сервиса тврди: “Ако ваша класа испуњава
конкретни интерфејс, ја ћу онда пружити услугу.”
- Размотримо конкретан пример. Метод sort у класи Arrays обећава да
ће сортирати низ објеката, али под једним условом:
- објекти у низу морају сами знати како да се упореде тј. морају припадати класи која имплементира интерфејс Comparable. public interface Comparable { int compareTo ( Object other ); }
- Да би класа имплементирала интерфејс Comparable она мора да
садржи метод compareTo.
Интерфејси у ЈДК-у
Математички факултет (^) {vladafvladaf@matf.bg.ac.,kartelj}@matf.bg.ac.rs rs 17 / 23
- java.lang.Comparable
- int compareTo(Object other)
- java.util.Arrays
- static void sort(Object[] a)
- Сортира елементе низа побољшаном верзијом сортирања учешљавањем (енг. Merge sort).
- Елементи низа морају имплементирати Comparable интерфејс.
- static void sort(Object[] a, Comparator c)
- Друга варијанта која користи експлицитни начин поређења дефинисан класом Comparator
- static void sort(Object[] a)
- java.util.Comparator
- int compare(Object o1, Object o2)
- Пореди два објекта и враћа:
- негативан број ако први претходи другом,
- враћа нулу ако су исти по уређењу
- или позитиван број ако други претходи првом.
- Пореди два објекта и враћа:
- int compare(Object o1, Object o2)
Интерфејси у ЈДК-у (5)
Математички факултет (^) {vladafvladaf@matf.bg.ac.,kartelj}@matf.bg.ac.rs rs 18 / 23
1. Заједничке операције и поља сместити у надкласе.
Тако је оформљена класа Person као надкласа Employee и Student.
2. Избегавати употребу заштићених поља.
- Модификатор protected не пружа много заштите, из два разлога:
1. Може се увек направити поткласа неке класе и тиме
приступити protected променљивој.
2. У програмском језику Јава све класе у истом пакету имају
приступ protected пољима, тако да се класа може сместити у
исти пакет и тиме омогућити приступ.
- Међутим, protected методи могу бити корисни за назначавање да
дати метод није спреман за општу употребу и да треба да буде
редефинисан у поткласама.
Препоруке за наслеђивање
Математички факултет (^) {vladafvladaf@matf.bg.ac.,kartelj}@matf.bg.ac.rs rs 19 / 23
3. Користити наслеђивање за моделирање односа “јесте”.
- Понекад програмери претерују у коришћењу наслеђивања. Претпоставимо да нам требају радници по уговору, тј. класа Contractor. Радници под уговором садрже имена и датум запослења, али не садрже плату, већ се плаћају по сату. Иако постоји изазов да се класа Contractor направи као подкласа класе Employee којој је додато поље hourlyWage, то не би била добра идеја јер би тада примерак класе Contractor садржао и поље за плату и поље за сатницу, а то би водило у проблеме. Наиме однос између ентитета радник по уговору и запослени не пролази тест “јесте”. Радник по уговору није специјалан случај запосленог.
Препоруке за наслеђивање (2)
Математички факултет (^) {vladafvladaf@matf.bg.ac.,kartelj}@matf.bg.ac.rs rs 20 / 23
4. Не користити наслеђивање сем уколико оно има смисла
за све методе класе из које се наслеђује.
Претпоставимо да желимо да направимо класу за празнике Holiday.
Будући да је сваки празник дан, а да су дани примерци класе
GregorianCalendar, то можемо користити наслеђивање.
class Holiday extends GregorianCalendar {... }
На несрећу, скуп празника није затворен у односу на наслеђене операције.
Један од јавних метода класе GregorianCalendar је метод add.
Међутим, овај метод може да претвори празник у нерадни дан:
Holiday christmas ;
christmas. add ( Calendar. DAY_OF_MONTH , 12 );
Стога, у овом примеру наслеђивање није адекватно.
Препоруке за наслеђивање (3)
Математички факултет (^) {vladafvladaf@matf.bg.ac.,kartelj}@matf.bg.ac.rs rs 21 / 23
5. Приликом превазилажења метода не мењати очекивано
понашање тј. поштовати принцип замене.
Принцип замене се примењује и на синтаксу и на понашање.
При превазилажењу метода се не сме неразумно мењати његово понашање.
На пример, ако се „поправи“ проблем са методом add у класи Holiday тако
да сада add пребацује на следећи празник, тада бива нарушен принцип
замене.
Наиме, секвенца нареби:
int d1 = x. get ( Calendar. DAY_OF_MONTH );
x. add ( Calendar. DAY_OF_MONTH , 1 );
int d2 = x. get ( Calendar. DAY_OF_MONTH );
System. out. println ( d2 - d1 );
треба да има очекивано понашање, тј. да врати 1 , без обзира да ли је
променљива x типа GregorianCalendar или Holiday.
Препоруке за наслеђивање (4)
Математички факултет (^) {vladafvladaf@matf.bg.ac.,kartelj}@matf.bg.ac.rs rs 22 / 23
6. Користити полиморфизам, а не информације о типу.
- Кад год се наиђе на код облика: if ( x is of type 1 ) action1 ( x ); else if ( x is of type 2 ) action2 ( x );
треба размотрити могућност полиморфизма.
- Да ли action1 и action2 представљају заједничке концепте?
- Ако је одговор да, тај заједнички концепт треба да буде
метод заједничке надкласе или интерфејса.
- Потом се једноставно треба позвати x.action(); па да
механизам динамичког активирања који је инхерентан
полиморфизму покреће одговарајућу акцију.
Препоруке за наслеђивање (5)
Математички факултет (^) {vladafvladaf@matf.bg.ac.,kartelj}@matf.bg.ac.rs rs 23 / 23