1. Въведение

Искаме да посветим днешния урок на капсулирането . Вече знаете Howво е това в общи линии.

Капсулиране

Какви са предимствата на капсулирането? Има доста от тях, но мога да откроя четири, които според мен са основните:


2. Валидно вътрешно състояние

В програмите често възникват ситуации, когато даден обект взаимодейства с няколко други класа. Тези взаимодействия с обекта могат да повредят данните в обекта, което прави невъзможно обектът да продължи да работи според очакванията.

В резултат на това обектът трябва да следи всички промени във вътрешните си данни or още по-добре сам да направи промените.

Ако не искаме някоя променлива да бъде променяна от други класове, тогава я декларираме като частна. След като направим това, само методите от неговия собствен клас имат достъп до него. Ако искаме променливите да са само за четене, тогава трябва да добавим public getterза съответните променливи.

Да предположим например, че искаме всички да могат да знаят броя на елементите в нашата колекция, но не искаме те да могат да променят колекцията без наше разрешение. След това декларираме private int countпроменлива и public getCount()метод.

Правилното използване на капсулиране гарантира, че нито един клас няма директен достъп до вътрешните данни на нашия клас, което следователно предотвратява всяHowви промени извън нашия контрол. Тези промени са възможни само чрез извикване на методите от същия клас като променливите, които се променят.

Най-добре е да приемете, че другите програмисти винаги ще използват вашите класове по начина, който е най-удобен за тях, а не по начина, който е най-безопасен за вас (за вашия клас). Това поведение е източник Howто на грешки, така и на опити за предотвратяването им.


3. Валидиране на аргументите на метода

Понякога трябва да валидираме аргументите, предадени на нашите методи. Например, да кажем, че имаме клас, който представлява човек и ви позволява да зададете рождена дата. Трябва да проверим всички входни данни, за да сме сигурни, че имат смисъл с логиката на програмата и логиката на нашия клас. Например да забраните рождена дата в 13-ия месец or на 30 февруари и т.н.

Защо някой ще посочи 30 февруари за своя рождена дата? Първо, това може да е потребителска грешка при въвеждане на данните. Второ, една програма може да има много грешки в себе си, преди да започне да работи като часовник. Например, възможна е следната ситуация.

Програмист пише програма, която идентифицира хора, чийто рожден ден е вдругиден. Например, да кажем, че днес е 3 март. Програмата добавя числото 2 към текущия ден от месеца и търси всички, които са родени на 5 март. Изглежда, че всичко е правилно.

Но когато дойде 30 март, програмата няма да намери никого, защото в календара няма 32 март. Една програма има много по-малко грешки, ако проверим данните, предадени на методите.

Спомняте ли си, когато изучавахме ArrayListи анализирахме неговия code? Видяхме, че методите getand setпроверяват дали indexе по-голямо or равно на нула и по-малко от дължината на масива. Нещо повече, тези методи хвърлят изключение, ако индексът е извън границите на масива. Това е класически пример за проверка на входа.


4. Минимизиране на грешките при промяна на codeа

Да предположим, че написахме супер полезен клас, когато участвахме в голям проект. Всички го харесаха толкова много, че други програмисти започнаха да го използват на стотици места в codeа си.

Класът беше толкова полезен, че решихте да го подобрите. Но ако премахнете няHowви методи от класа, codeът на десетки хора ще спре да се компorра. Ще трябва да пренапишат всичко. И колкото повече промени правите, толкова повече грешки ще създадете. Ще счупите много сборки и ще бъдете мразени.

Но когато променим методи, които са декларирани като частни, знаем, че никъде няма нито един друг клас, който да извиква тези методи. Можем да ги пренапишем, да променим броя на параметрите и техните типове и всеки зависим външен code ще продължи да работи. Е, поне ще се компorра.


5. Ние решаваме How нашият обект взаимодейства с външни обекти

Можем да ограничим някои от действията, които могат да се извършват с нашия обект. Да предположим например, че искаме даден обект да бъде създаден само веднъж. Дори и да е създаден на няколко места в проекта. И можем да направим това благодарение на капсулирането.

Капсулиране 2

Капсулирането ни позволява да добавим допълнителни ограничения , които могат да се превърнат в допълнителни предимства . Например, Stringкласът е имплементиран като неизменен обект. Обектът от Stringкласа е неизменен от момента на създаването му до момента на смъртта му. Всички методи на Stringкласа ( remove, substring, ...), връщат нов низ, без да правят промени в обекта, на който са извикани.

Капсулирането е много интересно нещо.