Основи на Java Static и Non-static
- Static
- Static променлива: Променлива декларирана с думата static. Принадлежи на целия клас. Заделя се само едно място в паметта и се споделя от всички обекти. Ако един обект промени стойността промяната се вижда от всички.
- Static метод: Метод деклариран с думата static. Това означава че метода принадлежи на класа. Има достъп до статичните обекти на този клас. Този метод може да пренапише стойност на всички статични данни.
- Static вложен клас: Държи се като напълно отделен външен клас. Не изисква създаването на обект от външен клас за да се използва
- Non-static
- Non-static променлива: Принадлежи на един обект. Всеки път когато напипеш new се заделя ново място в паметта. При промяна от един обект тя не се отразява на друг.
- Non-static метод: Това е метод който принадлежи на обект. Може да променя всякакви статични и нестатични данни. Без да създават инсатнции могат да имат достъп до статични методи и променливи.
- Non-static вложен клас е винаги свързан с обект от външния. Има достъп до всички полета на външния клас.
- Binding process
- Процес на свързване на извикването на метод с конкретния код за изпълнение.
- Static binding: По време на компилация компилатора знае кой метод ще бъде извикан. Пример е Overloading. Всеки static, private и final метод също са примери. Компилаторът казва: "Извикай метода на ред 50 в клас A." (Твърда връзка).
- Dynamic binding По време на изпълнение. Компилатора не знае кой метод ще се изпълни, защото зависи от реалния обект в паметта. Пример е основата на полиморфизма Оverriding. JVM проверява реалния тип на обкета по време на работа. Компилаторът казва: "Извикай метода с име X, но не знам на кой точно обект. Като тръгне програмата, провери какъв е обектът и намери метода му."
- Предимства:
- Static методи: Не хабим място в паметта. В Utility класовете (Помощните) има само статични методи които служат за обработка на данни. Можем да създадем обекти така вместо с конструктор. LocalDate today = LocalDate.now()
- Non-static методи Когато искаме да работим индивидуално с данните.
Final
- Final променливи
- Това са променливи които не могат да бъдат променени Final variable: final int ONE = 1; Blank final variable: final int ONE; Static final variable: static final int ONE = 1; Static final blank variable: static final int ONE;
- Final с рефернтен тип данни: При примитиви (напр. int): Променливата съдържа самата стойност. Затова final заключва директно стойността и тя не може да се смени. При референтни типове (напр. StringBuilder): Променливата пази адрес към Heap паметта. final заключва този адрес (не можем да насочим променливата към нов обект с new). Пример със StringBuilder: Можем да използваме методи като .append(), защото те променят вътрешното състояние на обекта, без да променят адреса му. Пример със String: Тъй като String е immutable (непроменим) по дизайн, ние не можем да променим вътрешното му състояние. А тъй като е и final, не можем да сменим и адреса. Резултатът е пълна константа.
- Final методи Когато сложим ключовата дума пред метод това означава че метода вече не може да бъде пренаписван. При тези методи имаме Static Binding тъй като метода не може да бъде променен и компилатора няма нужда да чака програмата да тръгне за да разбере коя версия на метода ще се изпозлва.
- Final класове Това означава че класа не може да се наследява. Модификатори за достъп
- Private:
- При променлива Почти всички полета в един клас трябва да са private.
- При метод Когато метода е само помощен за вътрешна логика на класа.
- При конструктори Когато искаш да забраниш създаването на много обекти(Singleton pattern). Също така при Utility класовете, които са пълни само със статични методи. Няма смисъл да създаваш нов обект например от класа Math. Няма смисъл защото тези класове нямат памет. Методите са общи за всички и за това не се нуждаем от обект.
- При вътрешни класове За да скриеш помощни класове.
- Когато маркираш нещо като Private то е видимо само в рамките на класа. Наследниците не могат да го ползват директно.
- Това всъщност се нарича капсулация и един четирите принципа на ООП.
- След като полето е скрито достъпът до него става чрез getters и setters.
- Public:
- Напълно различно от private. Когато маркираш нещо като public това означава че е видимо навсякъде. Ако не е в същия пакет просто трябва да се импортне пакета и пак ще се вижда.
- Public дефинира интерфейс на твоя клас kъм външния свят. Това са методите които искаш другите програмисти да изпозлват. Main метода винаги е public за да може JVM да го извика.
- Единствения път в който поле е public е когато е константа. Тогава няма проблем защото не може да бъде променено.
- В един .java файл може да имаш само един public клас. Името на този клас задължително трябва да съвпада с името на файла. Не може да имаш примерно public class A; public class B защото java няма да знае как да кръсти файла ти.
- Protected:
- Protected означава че това което е маркирано като protected ще бъде видимо само в пакета плюс наследниците на класа.
- Използва се когато искаш нещо да се вижда само от наследниците, но не и от други.
- Default:
- Това е package-private. Вижда се само в рамките на пакета. Няма ключова дума просто не пишеш нищо.
- Ипзолзва се за да групираш класове които са в един пакет, без да показваш вътрешната им връзка. Важно! Най-важния метод който трябва да е private е конструктора. Това се прави при Singleton Pattern за да гарантираш че от този клас може да има само една инстанция. Ако е public всеки може да напише new и да създаде втори обект.
Как работи Enum? Когато напишеш например: Enum Day { MONDAY, TUESDAY } Компилаторът всъщност го превръща в това: Final class Day extends java.lang.Enum { public static final Day MONDAY = new Day(); public static final Day TUESDAY = new Day();
private Day() {} – конструктора е private и не можеш да правиш нови данни. } Можеш да добавяш полета конструктори и методи точно както и в нормален клас. Тъй като са статични константи може да се сравняват с ==