Fundamentals Flashcards
DataStructures, OOP, Interfaces, Classes, Packages, Working with Date/Time, Functions, Loops, Exception Handling, Working with Files and APIs
Overriding i Overloading
Overloading (Preopterećenje metoda) znači definisanje više metoda sa istim imenom, ali sa različitim brojem, tipom ili redosledom parametara u istoj klasi.
Metode imaju isto ime, ali različite potpise (broj, tip ili redosled parametara)
Sve metode su definisane u istoj klasi
Compile-Time polimorfizam (statički) - odabir metode se dešava tokom kompajliranja na osnovu parametara
Overloading NE zavisi od povratnog tipa metode
public int add(int a, int b) { … }
public double add(int a, int b) { … } // Neće raditi, potpisi su isti!
Overriding (Nadjačavanje metoda) znači definisanje metode u podklasi koja ima isti potpis (ime, parametre i povratni tip) kao metoda u njenoj nadklasi
Runtime polimorfizam (dinamički) - metoda koja će se izvršiti odlučuje se tokom izvršavanja, na osnovu objekta
Potpis metode mora biti isti (ime, parametri i povratni tip)
Vidljivost metode (overriding metoda ne može imati užu vidljivost od metode u nadklasi)
Annotaion @Override (nije obavezan, ali se preporučuje)
Ne mogu se override-ovati final, static i private metode
POVRATNI TIP NIJE DEO POTPISA METODE U SLUČAJU OVERLOADING-A!
Inače, povratni tip nije deo potpisa metode, samo kod overridinga jeste
Kopirajući konstruktor
Kreira novi objekat kopiranjem vrednosti polja drugog objekta iste klase
Konstruktori u istoj klasi mogu biti overloaded ukoliko imaju različite potpise.
public class Person {
String name;
int age;
public Person(String name, int age) { this.name = name; this.age = age; } // Kopirajući konstruktor public Person(Person other) { this.name = other.name; this.age = other.age; } }
public class Main {
public static void main(String[] args) {
Person person1 = new Person(“Alice”, 25);
Person person2 = new Person(person1);
System.out.println(person2.name); // Alice System.out.println(person2.age); // 25 } }
Globalne promenljive
u Javi ne postoje prave globalne promenljive kao u C++, međutim, statičke promenljive i metode omogućavaju funkcionalnost koja je slična globalnim promenljivima jer su povezane sa istom klasom a ne sa instancom objekta.
sve instance klase dele jednu kopiju statičke promenljive, koje se inicijalizuju samo jednom kada se klasa učita u memoriju
statičke promenljive se često koriste za konstante ili globalne podatke koje dele sve instance
statičke metode ne mogu direktno pristupati nestatičkim poljima i metodama jer nisu povezane sa nijednom instancom
Enum
Tip podataka za definisanje skupa konstantnih vrednosti. To su unapred definisane, fiksne vrednosti koje se ne mogu menjati tokom izvršavanja programa.
Enum je specijalan tip klase
Vrednosti u enum-u su konstante i implicitno su public static final
Enum je immutable
Svaka vrednost u enum-u predstavlja jedinstvenu instancu enum klase
enum može sadržati polja, metode, konstruktore
public enum Day {
MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY, SUNDAY
}
public class Main {
public static void main(String[] args) {
Day today = Day.MONDAY;
System.out.println(today); // Ispisuje: MONDAY
}
}
public enum HttpStatus {
// 1xx Informational
CONTINUE(100, “Continue”),
SWITCHING_PROTOCOLS(101, “Switching Protocols”),
// 2xx Success OK(200, "OK"), CREATED(201, "Created"), ACCEPTED(202, "Accepted"), // 3xx Redirection MOVED_PERMANENTLY(301, "Moved Permanently"), FOUND(302, "Found"), // 4xx Client Errors BAD_REQUEST(400, "Bad Request"), UNAUTHORIZED(401, "Unauthorized"), FORBIDDEN(403, "Forbidden"), NOT_FOUND(404, "Not Found"), // 5xx Server Errors INTERNAL_SERVER_ERROR(500, "Internal Server Error"), NOT_IMPLEMENTED(501, "Not Implemented"), BAD_GATEWAY(502, "Bad Gateway"); private final int code; private final String message; // Konstruktor HttpStatus(int code, String message) { this.code = code; this.message = message; } // Getter za kod public int getCode() { return code; } // Getter za poruku public String getMessage() { return message; } // Metoda za pronalaženje statusa po kodu public static HttpStatus fromCode(int code) { for (HttpStatus status : HttpStatus.values()) { if (status.getCode() == code) { return status; } } throw new IllegalArgumentException("Invalid HTTP status code: " + code); } }
public class Main {
public static void main(String[] args) {
HttpStatus status = HttpStatus.OK;
System.out.println(“Code: “ + status.getCode()); // Ispisuje: Code: 200
System.out.println(“Message: “ + status.getMessage()); // Ispisuje: Message: OK
}
}
Relacije u Javi
Asocijacija - veza između 2 klase gde jedan objekat koristi funkcionalnosti drugog objekta. Ovo može biti jednosmerno ili dvosmerno.
Kompozicija (HAS-A) jedna klasa ne može postojati bez druge (auto ima motor, motor ne može postojati bez auta)
Agregacija (HAS-A) slabija veza od kompozicije, celina poseduje reference na delova, ali delovi mogu postojati samostalno (Profesor ima listu studenata, ali studenti mogu postojati i bez profesora)
Generalizacija/Specijalizacija (IS-A) odnosi se na nasleđivanje
Relacija korišćenja - označava privremenu zavisnsot jedne klase od druge. Jedna klasa koristi drugu klasu kao parametar illi lokalnu promenljivu u metodi (klasa Order koristi klasu Product u svojoj metodi za izračunavanje ukupne cene)
Notacija:
Kompozicija - crni romb
Agregacija - prazan romb
Generalizacija - prazna strelica prema superklasi
Relacija korišćenja - isprekidana strelica prema klasi koja se koristi
Collection Hierarchy in Java
Iterable:
Collection:
List (ArrayList, LinkedList, Vector)
Queue
Set
Array List je bazirana na nizu, ima brzo pristupanje, ali sporije dodavanje i brisanje (o(n))
LinkedList je bazirana na povezanoj listi i ima efikasno dodavanje i brisanje (o(1)), ali sporiji pristup elementima (o(n))
Vector je slična struktura ArrayList-i, ali je sinhronizovan
Stack nasleđuje vektor
String klasa u Javi
Immutable (jednom kreirani String objekti ne mogu biti promenjeni)
Svaka operacija koja menja String, zapravo kreira novi objekat
Java koristi String pool gde se čuvaju jedinstvene instance String objekata
Kada kreiramo String literal, JVM proverava da li isti String već postoji u pool-u i koristi ga, umesto da kreira novu instancu
Working with Date-Time u Javi
Stare klase: java.util.Date i java.util.Calendar
Moderne klase: java.time (API od Jave 8)
Klase za rad s datumima i vremenom:
LocalDate
LocalTime
LocalDateTime
ZonedDateTime
Duration i Period
LocalDate today = LocalDate.now();
LocalDate birthday = LocalDate.of(1995, 12, 15);
LocalTime now = LocalTime.now();
Exception Handling
Izuzetak je događaj koji se javlja tokom izvršavanja programa i narušava normalan tok izvršavanja. Izuzeci nisu sintaksne greške, pa program koji izaziva ovakve situacije može normalno da se kompajlira i pokrene.
Izuzeci u Javi su implementirani u vidu klasa. Svaki put kada se desi greška, napravi se po jedan objekat klase koja predstavlja izuzetak, npauni odgovarajućim podacima i prosledi Javinom mehanizmu za obrađivanje izuzetaka.
Object -> Throwable
1. Error (IOError, ThreadDeath, VMError…)
2. Exception
2.1 RuntimeException (NullPointer, Arithemtic)
2.2 IOException
2.3 SQLException
Error predstavlja greške na nivou sistema, od kojih program obično ne može da se oporavi. Exception predstavlja greške koje program može obraditi.
Exception se deli na dve vrste:
Checked - proverava ih komapjler, moraju biti uhvaćeni (try-catch) ili deklarisani u throws
Unchecked - nisu proveravani od strane kompajlera i javljaju se tokom izvršavanja (runtime)
RuntimeException i Error spadaju u unchecked izuzetke
Apstraktne klase i interfejsi
Oba se koriste za apstrakciju, tj definisanje zajedničkog ponašanja koje klase treba da implementiraju.
Apstraktna klasa - klasa koja može sadržati apstraktne metode, metode sa implementacijom, polja i konstruktore
Ne može se direktno instancirati
Kada klasa nasledi AK, mora implementirati sve njene apstraktne metode ili i sama postati apstraktna. Može se naslediti samo jedna AK. Obezbeđuje osnovnu strukturu klase sa zajedničkim ponašanjem.
Interfejs je potpuno asptraktan tip koji sadrži samo deklaracije metoda (do Jave 7). Od Jave 8 interfejs može da sadrži default i static metode. Od Jave 9 može da sadrži i privatne metode.
Kompatibilnost klasa kod nasleđivanja
Klasa koja nasleđuje drugu klasu automatski nasleđuje sve javne i zaštićene članove nadklase
Podklasa može redefinisati (override) metode nadklase da prilagodi njihovo ponašanje
Kompatibilnost tipova kod nasleđivanja:
Upcasting (implicitno kastovanje) - podklasa se može automatski tretirati kao nadklasa
Animal a = new Dog();
Downcasting (eksplicitno kastovanje):
Nadklasa se može kastovati u podklasu, ali samo ako objekat zaista pripada podklasi
Animal a = new Dog();
Dog d = (Dog) a;
equals() metoda
equals() metoda u Javi poredi sadržaj objekata, dok operator == poredi reference tj adrese u memoriji
Da bismo poređenje prilagodili sadržaju objekata, treba da predefinišemo (override) equals() metodu.
JavaBeans specifikacija
JavaBeans su klase koje implementiraju JavaBeans specifikaciju
Osnovne karakteristike JavaBeans klasa:
JavaBean mora imati getter i setter metode za pristup privatnim poljima.
Polja klase moraju biti privatna
Mora imati konstruktor bez argumenata (podrazumevani konstruktor).
Poželjno je da klasa implementira interfejs Serializable.
Working with Files and APIs in Java
Ulazni tokovi (InputStream/Reader) - koriste se za čitanje podataka iz izvora (npr fajla)
Izlazni tokovi (OutputStream/Writer) - koriste se za pisanje podataka u odredište (npr fajl)
Tokovi bajtova (InputStream/OutputStream) - za rad sa binarnim podacima
**Tokovi karaktera **(Reader/Writer) - za rad sa tekstualnim podacima
import java.io.*;
public class FileWriteExample {
public static void main(String[] args) {
try (BufferedWriter writer = new BufferedWriter(new FileWriter(“output.txt”))) {
writer.write(“Hello, World!”);
writer.newLine();
writer.write(“Java I/O example.”);
} catch (IOException e) {
e.printStackTrace();
}
}
}
Serijalizacija je proces pretvaranja objekata u niz bajtova kako bi se sačuvao u fajl ili poslao preko mreže. Deserijalizacija je obrnut proces.
Ključni elementi serijalizacije:
1. Klasa mora implementirati interfejs Serializable.
2. Koristi se klase poput ObjectOutputStream za serijalizaciju i ObjectInputStream za deserijalizaciju.
BufferedReader interno kroisti bafer (privremenu memoriju) kako bi smanjio broj I/O operacija
Čitanje se obavlja u većim blokovima podataka, a ne karakter po karakter, što povećava performanse