блябли Flashcards
Принципи на ООП
Полиморфизъм, Енкапсулация, Наследяванер Абстракция,
Какво е клас
Прототип от който се създават обекти; определя какво състояние могат да имат неговите инстанции, т.е. някакви характеристики които всеки обект от този клас ще има, и поведение, т.е. някакви операции, които могат да се извършват с всеки от обектите
Какво е обект
Обектът е конкретeн представител на един клас, има конкретни характеристики (полета) и конкретно поведение (методи)
Какво са модификаторите за достъп + пример за всеки кога се използва?
Начин да определим колко свободно може да се достъпва типа, към който е приложен модификаторът. Има 4 вида модификатори:
- public - може да се достъпва от всякъде; когато знаем че този метод/клас/променлива ще се използва извън класа
- protected - може да се достъпва в пакета в който се намира както и от всички наследници, дори и да са извън пакета
- package-private - това е дефолт модификатора за достъп; може да се достъпва само в рамките на пакета в който се намира
- private - може да се достъпва само в рамките на класа ; например за полета в рамките на един клас
Статични инициализатори - обясни?
Пример?
блок от код без конкретно име или ретърн тип, само със static ключова дума преди него; целта му е да се инициализира статично поле; обикновено се използва когато иницализацията изисква повече от едно действие
Пример - когато трябва да инициализираме лист който вътре да има някакви дефолтни стойности
Method overloading - обясни?
Ползи?
Пример ?
Това е способността в рамките на един клас да имаме повече от един метод с едно и също име, но различни сигнатури (може да прима различен брой и/или различни типове). Известно е още като статичен полиморфизъм, програмата решава кой от двата метода да използва по време на компилация
Ползи - не се налага да създаваме и да помним различни имена за методи които правят едно и също но приемат различен брой или тип параметри.
Пример - метод са сумиране на числа
Какво е енкапсулация?
Как се постига?
Какви са ползите?
“Опаковането” на данните и методите в рамките на едни клас, така че да не може да се достъпват и променят от вън и имплементацията вътре в класа да е скрита за неговите външни потребители.
- Постига се като направим всички полета на един клас private. В случай че логиката на програмата не изисква полетата да може да се променят, правим също всички setter-и private.
- Ползи: пълен контрол и сигурност, че данните вътре в класа са валидни и не биха могли да бъдат “замърсени” по някакъв начин от външни потребители; също така абстракция - външните потребители могат да използват публичните методи на класа като се абстрахират от вътрешната имплементация.
The rule of thumb is simple: make each class or member as inaccessible as
possible. In other words, use the lowest possible access level consistent with the
proper functioning of the software that you are writing.
Information hiding is important for many reasons, most of which stem from
the fact that it decouples the components that comprise a system, allowing them to
be developed, tested, optimized, used, understood, and modified in isolation. This
speeds up system development because components can be developed in parallel.
It eases the burden of maintenance because components can be understood more quickly and debugged or replaced with little fear of harming other components.
While information hiding does not, in and of itself, cause good performance, it
enables effective performance tuning: once a system is complete and profiling has determined which components are causing performance problems, those
components can be optimized without affecting the correctness of others. Information hiding increases software reuse because components that aren’t tightly coupled
often prove useful in other contexts besides the ones for which they were designed.
If a top-level class or interface can be made package-private, it should be.
By making it package-private, you make it part of the implementation rather than
the exported API, and you can modify it, replace it, or eliminate it in a subsequent
release without fear of harming existing clients.
Какво е наследяване?
Защо ни е наследяването – ползи?
Множествено наследяване в джава?
Наследяване - възможността един клас да наследява друг клас - т.е. да има същите полета и методи;
Ползи - наследяването е полезно, когато искаме да преизползваме базовите методи и полета на един клас, но да ги разширим в рамките на друг клас. По този начин избягваме повторението на кода който е в базовия клас и в неговия subclass имплементираме само допълнителните функционалности и полета.
В случай че искаме да променим имплементацията на някой от наследените методи можем да го override-нем
Недостатъка е че child класа става тясно свързан и зависим от имплементацията на базовия клас - например ако метод се изтрие от базовия клас, наследниците му ще трябва да бъдат рефакторирани (затова в повечето случаи се предпочита композиция пред наследяване)
Важно: private полетата на един базов клас не са достъпни в неговия child клас освен чрез конкретна негова инстанция!
В джава няма множествено наследяване, освен при интерфейсите.
Какво е полиморфизъм?
Ползи?
Полиморфизъм е способността на един обект да приема много форми. Най-често това се проявява когато реферираме чрез базов клас към child клас - например когато третираме story като work item.
Ползи - в зависимост от това дали се обръщаме към един обект като към част от негов parent клас или не можем да използваме различни имплементации на един и същи метод с него (благодарение на method overriding)
Какво е абстракция?
Ползи?
Скриването на имплементационните подробности от потребителя, показване само на функционалстотие. По този начин потребителя може да използва функционалстта без да се интересува вътрешно как тя работи.
Method overriding - обясни?
Ползи?
Възможността два класа (родител и наследяващ) да имат методи с едно и също име и сигнатура които обаче имат различна имплементация. По този начин наследяващия клас може да има своя имплементация на методи които вече съществуват в класа - родител.
Ползи - за да има по-различна имплементация в наследяващия клас не ни се налага да правим промени в класа - родител; всеки наследяващ клас може да има различна имплементация на този метод; в крайна сметка можем да третираме обектите от наследяващите класове като обекти от класа-родител (т.е. да работим на по-високо ниво на абстракция), като програмата решава кой метод да изпълни по време на изпълнение ( в зависимост от конкретния тип на обекта).
When a parent class reference points to the child class object then the call to the overridden method is determined at
runtime
!!! модификаторите за достъп на override-ващ метод могат да бъдат същите или по-свободни, не и по рестриктивни;
чрез думата super можем да извикаме override-натия метод в класа-родител - по този начин можем да използваме неговата имплементация и да я разширим без да повтаряме код
Какво е абстрактен клас?
Интерфейс?
Разлика между двете?
кога ползваме абстрактен клас?
кога ползваме интерфейс?
- Абстрактен клас е начин да постигнем абстракция (т.е. да скрием имплементационните подробности и да предоставим само функционалността на потребителя). Това е клас който не може да се инстанцира. Задължително трябва да се наследява и има свои полета и методи които се наследяват от неговите наследници. В рамките на абстрактния клас създаваме абстрактни методи (имат единствено сигнатура, но не и имплементация), които е задължително да бъдат override-нати в наследавящите класове, за да получат конкретна имплементация. Абстрактните методи реално са общо поведение, което всеки от наследяващите класове е длъжен да има.
- Интерфейс - друг начин да постигнем абстракция. Няма полета, съдържа само абстрактни методи които по default са публични, може да има също статични методи и променливи. Може да има default методи с имплементация, но не е желателно. Един интерфейс може да наследява много други интерфейси. Когато един клас имплементира интерфейс, е длъжен да override-не всичките му абстрактни методи или той самият да бъде абстрактен. Един клас може да имплементира много интерфейси. Идеята на интерфейса е да съдържа общото поведение на група от класове, които го имплементират. По този начин си осигуряваме по-добра абстракция когато работим на ниво интерфейс (и се възползваме от полиморфизъм)
- Прилики: позволяват дефинирането на общо поведение чрез абстрактни методи; позволяват програмиране на по-високо ниво на абстракция и полиморфизъм
- Разлики: абстрактния клас все пак има състояние и може да има базови методи с имплементация които да не са абстрактни
- ползваме абстрактен клас когато: има ясно изразена йерархия, искаме да има вътре някакво състояние, искаме да смесим абстрактно поведение с конкретна имплементация
- използаме интерфейс когато: искаме да определим общо поведение за група от класове; искаме да дефинираме някакви допълнителни способности, които някои класове ще имат, но други класове няма да имат; имаме нужда от множествено наследяване
Как постигаме силна кохезия и loose coupling?
- Кохезия - колко силно свързани помежду си са елементите в един модул (клас/метод/пакет); кохезията трябва да е силна, за да можем по-лесно да се справяме със сложността на програмата и да я поддържаме и разширяваме по лесно
- как се постига: да имаме добре дефинирани абстракции; класовете да имат силно свързани помежду си функционалности които имат едно предназначение; трябва да има малко полета и всеки следващ метод в рамките на класа да използва все повече полета; слабата кохезия си личи когато един клас може да бъде разделен на два или повече
- къплинг - степента на която всеки модул зависи от други модули; къплинга трябва да е рехав, за да можем по лесно да поддържаме програмата и да я разширяваме;
- как? - всички класове трябва да имат малки, директни и видими връзки към другите класове (за да може когато правим една промяна тя да се отразва само на един клас а не на много класове); един модул трябва лесно да може да се използва от други модули; трява да се програмира на ниво интерфейс
Какво е композиция?
Използване на един обект като поле в друг клас (has-a връзка). Винаги е за предпочитане пред наследяване ако логиката го позволява, защото по този начин имаме loose coupling.
Какво е финален клас?
Клас който не може да се наследява. Правим такива класове например ако създаваме библиотека и не искаме нейните потребители да могат да променят имплементацията.
За какво използваме new?
За да инстанцираме класове - с new отделяме памет за новия обект и връщаме неговата референция към тази памет
За какво използваме this
само с this викаме конструктор от същия клас, за да го overload-нем; в този случай this трябва да е първия ред в конструктора
с this.поле викаме сегашната инстанция на някое поле; използва се в случаите когато има конфликт между имената на параметрите на един метод и имената на променливите които се ползват в него