diff --git a/02-oop-in-java-i/README.md b/02-oop-in-java-i/README.md new file mode 100644 index 00000000..8c38cd0f --- /dev/null +++ b/02-oop-in-java-i/README.md @@ -0,0 +1 @@ +# Обектно-ориентирано програмиране с Java (част I) diff --git a/02-oop-in-java-i/lecture/images/02.1-oop.jpg b/02-oop-in-java-i/lecture/images/02.1-oop.jpg new file mode 100644 index 00000000..b63051a0 Binary files /dev/null and b/02-oop-in-java-i/lecture/images/02.1-oop.jpg differ diff --git a/02-oop-in-java-i/lecture/slides.html b/02-oop-in-java-i/lecture/slides.html new file mode 100644 index 00000000..7e553acb --- /dev/null +++ b/02-oop-in-java-i/lecture/slides.html @@ -0,0 +1,29 @@ + + + + [MJT2025] Modern Java Technologies Lecture + + + + + + + + + + + + + diff --git a/02-oop-in-java-i/lecture/slides.md b/02-oop-in-java-i/lecture/slides.md new file mode 100644 index 00000000..da82d1ef --- /dev/null +++ b/02-oop-in-java-i/lecture/slides.md @@ -0,0 +1,976 @@ +class: center, middle + +# Обектно-ориентирано програмиране с Java + +![Java OOP](images/02.1-oop.jpg) + +18.10.2023 + +--- + +### Предната лекция говорихме за: + +- Tиповете данни +- Оператори, изрази, statements +- Условия и разклонения +- Итерация / Цикли +- Низове и операции с тях +- Масиви +- Функции + +--- + +### Днес ще разгледаме: + +- Класове и обекти +- Абстрактни класове и интерфейси +- Фундаменталните ООП принципи + - Енкапсулация + - Наследяване + - Полиморфизъм + - Абстракция + +--- + +### Обектно-ориентирано програмиране + +- Родено е от необходимостта за по-добър контрол над едновременната модификация на споделени данни +- Основната идея е, да няма директен достъп до данните, а те да се достъпват през нарочен за целта слой код +- Понеже данните трябва да се предават и модифицират, се ражда концепцията за обект + +--- + +### Обект + +- Обект в най-общ смисъл е множество данни, които могат да се предават и достъпват само чрез множество методи, които се подават заедно с данните +- Данните съставляват *състоянието* на обекта, а методите съставляват *поведението* на обекта +- Състоянието на обекта е скрито (*енкапсулирано*) от директен достъп +- Обектът е инстанция (представител) на даден клас. Обекти се създават явно чрез оператора `new` или неявно, и живеят в heap паметта + +--- + +### Създаване на обекти + +```java +String message = new String("Operation completed."); // explicit +Integer studentsCount = Integer.valueOf(60); // implicit +int[] intArr = new int[100]; // explicit +String[] stringArr = {"Some", "example"}; // implicit +stringArr = new String[]{"Changed", "my", "mind"}; // explicit +``` + +--- + +### Клас + +- Клас – дефиниция на (клас от) обекти + - описва състояние чрез член-данни (член-променливи) + - описва поведение чрез методи +- Конструктор(и) +- Метод(и) +- Възможно е даден клас да няма състояние или да няма поведение +- Всеки клас има определен *интерфейс* - формално описание на начина, по който други обекти могат да взаимодействат с него + +--- + +### Метод на клас + +- Функция за манипулиране на състоянието на класа + - име и списък от параметри (*сигнатура*) + - броят на параметрите се нарича *арност* + - два метода имат еднаква сигнатура, ако имат еднакви имена, еднаква арност и еднаква последователност от типове в списъка от параметри + - модификатори, тип на връщаната стойност, сигнатура и тяло, оградено с {} + - тялото може да съдържа декларации на локални променливи и statements + - може да има странични ефекти + +--- + +### Метод на клас + +```java +public class AdmissionTestProblems { + + public static int getMissingNo(int a[]) { + int i, total, n = a.length; + total = n * (n + 1) / 2; + + for (i = 0; i < n; i++) { + total -= a[i]; + } + + return total; + } + +} +``` + +--- + +### Методи с променлив брой аргументи + +- специален вид параметър на метод: редица от нула или повече аргументи от един и същи тип +- Нарича се *varargs*, от *variable arguments* +- Синтаксис: име на тип, следван от три точки (многоточие) +- Ако метод има varargs параметър, той трябва да е един и да е последен в списъка +- При достигане до varargs параметър, компилаторът създава масив от останалите аргументи и ги подава на метода като масив +- В тялото на метода се достъпва като масив + +--- + +### Методи с променлив брой аргументи + +```java +// A method that takes variable number of integer arguments +static void funWithVarargs(int... a) { + System.out.println("Number of arguments: " + a.length); + + // using for-each loop to display contents of a + for (int i : a) { + System.out.print(i + " "); + } +} + +public static void main(String[] args) { + // standard syntax +} + +public static void main(String... args) { + // varargs syntax - equivalent to the above +} +``` + +--- + +### Статични член-променливи и статични методи + +- Те са част от класа, а не от конкретна негова инстанция (обект) +- Могат да се достъпват, без да е създаден обект: само с името на класа, точка, името на статичната член-променлива или метод + +
+ +```java +System.out.println(Math.PI); // 3.141592653589793 +System.out.println(Math.pow(3, 2)); // 9.0 +``` + +--- + +### Статични член-променливи + +- Статичните член-променливи имат едно-единствено копие, което се споделя от всички инстанции на класа + - ако са константи, пестим памет (няма смисъл да се мултиплицират във всяка инстанция) + - ако са променливи, всяка инстанция "вижда" и променя една и съща стойност, което е механизъм за комуникация между всички инстанции на дадения клас + +--- + +### Статични методи + +- Статичните методи имат достъп само до статичните член-променливи и други статични методи на класа +- Нестатичните методи имат достъп както до статичните, така и до нестатичните членове на класа + +--- + +### Статични методи + +```java +public class Utils { + public static final double PI = 3.14; // constant + private static int radius = 10; // static member + private String fact5 = "5!"; // non-static member + + // static method + public static long fact(int n) { + if (n == 1) { return 1; } else { return n * fact(n - 1); } + } + + // non-static method + public String getFact() { + return fact5; + } + + public static void main(String[] args) { + System.out.println("Perimeter is " + 2 * Utils.PI * radius); + System.out.println(new Utils().getFact() + "=" + Utils.fact(5)); + Utils.getFact(); // won't compile + } +} +``` + +--- + +### Ключовата дума `this` + +- Референция към конкретния обект +- Неявно се подава като параметър на всеки конструктор и нестатичен метод на класа +- Употребява се за: + - достъпване на член-променливи, "скрити" от едноименни параметри на метод или локални променливи + - извикване от конструктор на друг overloaded конструктор в същия клас + - извикване на произволен метод на класа + +--- + +### Ключовата дума `this` + +```java +public class Human { + + private String name; + + public Human() { + // Извикване на overload-натия конструктор със String параметър + this("Unknown"); + } + + public Human(String name) { + // Достъпване на член-променлива, скрита от едноименен параметър + this.name = name; + } + + public void whoAmI() { + System.out.println("My name is " + name); + } + +} +``` + +--- + +### Обект - конкретна инстанция на даден клас + +```java +public class MainApp { + + public static void main(String[] args) { + Human ivan = new Human("Ivan"); + ivan.whoAmI(); + Human petar = new Human("Petar"); + petar.whoAmI(); + } + +} +``` + +--- + +### Пакети + +- Именувани групи от семантично свързани класове +- Служат за йерархично организиране на кода +- Съответстват на директорно дърво на файловата система +- Конвенция за именуване: + - само малки букви, точка за разделител + - компаниите използват обърнат домейн адрес + - `mail.google.com` → `com.google.mail` + +--- + +### Пакети + +- всеки Java клас се намира в някакъв пакет +- пакетът се указва в началото на сорс файла (преди дефиницията на класа) с ключовата дума `package` +- ако липсва `package` декларация, класът е в пакета по подразбиране (който няма име) - което е лоша практика + +
+ +```java +package bg.sofia.uni.fmi.mjt.example; + +public class Example { + // class Example is in package bg.sofia.uni.fmi.mjt.example +} +``` + +--- + +### Достъп до клас от друг пакет + +- Всеки клас има достъп по подразбиране (имплицитно) до: + - класовете от собствения си пакет + - класовете в пакета `java.lang` +- Ако искаме клас да има достъп до клас в някой друг пакет, трябва или експлицитно да го заявим с `import` декларация, която поставяме над декларацията на класа, или да се позоваваме до него с пълното му име, което включва и пакета му (не се препоръчва). +- `import` декларацията може да е за конкретен клас с пълното му име: име на пакет + `.` + име на клас, или на всички класове в даден пакет (т.нар. *wildcard import*: име на пакет + `.*`, което обаче е лоша практика откъм clean code) + +--- + +### Достъп до клас от друг пакет + +```java +package bg.sofia.uni.fmi.mjt.example; + +import java.util.Arrays; +import java.util.Scanner; + +public class StringUtils { + + public static void main(String[] args) { + Scanner scanner = new Scanner(System.in); + char[] tokens = scanner.nextLine().toCharArray(); + Arrays.sort(tokens); + // java.util.Arrays.sort(tokens); // the ugly alternative + System.out.println(tokens); + } + +} +``` + +--- + +### Достъп до клас от друг пакет + +- Статичните член-данни и методи се достъпват с префикс: името на класа, който ги съдържа и точка +
+`double r = Math.cos(Math.PI * 10.0);` +- `import static` конструкцията позволява статичните членове да се ползват директно по името си + +
+ +```java +import static java.lang.Math.cos; +import static java.lang.Math.PI; + +... + +double r = cos(PI * 10.0); + +``` + +--- + +### Достъп до клас от друг пакет + +- Прието е `import`-ите да се подреждат в сортиран лексикографски ред по `.` +- По-чисто е да се изброят конкретните класове от пакета, вместо wildcard import (тип `import java.util.*;`) + - IDE-тата обаче автоматично "collapse"-ват `import`-ите от един и същи пакет над някаква бройка - изключете тази "екстра" + +--- + +### Модификатори за достъп + +за top-level клас, т.е. невложен в друг + +
+ +| Модификатор | Видимост | +| :--------------- |:------------------------------------------------ | +| `public` | Достъпен за всеки клас във всеки пакет | +| без модификатор* | Достъпен само за класовете в собствения си пакет | + +
+ + +\* казваме също "package-private", "default" + + +--- + +### Модификатори за достъп + +За член-променливи и методи на клас + +
+ +| Модификатор | Клас | Пакет | Подклас | Всички други | +| :------------ |:----:|:-----:|:-------:|:------------:| +| `public` | да | да | да | да | +| `protected` | да | да | да | не | +| no modifier | да | да | не | не | +| `private` | да | не | не | не | + +--- + +### Енкапсулация + +Енкапсулацията адресира основния проблем, мотивирал създаването на ООП: по-добро управление на достъпа до споделени данни. + +--- + +### Енкапсулация + +- Множеството текущи стойности на член-данните на даден обект се наричат негово *състояние* +- Само вътрешните методи на даден обект имат достъп до неговото състояние, като правят невъзможни неочакваните промени на състоянието от външния свят +- В Java се постига чрез модификаторите за достъп + +--- + +### Енкапсулация – пример за нарушаване + +```java +public class Human { + + public String name; // no encapsulation! + + public Human(String name) { + this.name = name; + } + +} + +public class Main { + + public static void main(String[] args) { + Human ivan = new Human("Ivan"); + ivan.name = "Faked Ivan"; // Hm... + } + +} +``` + +--- + +### Енкапсулация – пример за спазване + +```java +public class Human { + + private String name; // stays hidden + + public Human(String name) { + this.name = name; + } + +} + +public class Main { + + public static void main(String[] args) { + Human ivan = new Human("Ivan"); + ivan.name = "Faked Ivan"; // won't compile + } + +} +``` + +--- + +### Наследяване + +- Позволява преизползване и разширяване на състояние и поведение на вече съществуващи класове +- Когато клас наследява друг клас, за него казваме, че е *наследник*, или *дете*, или *подклас*, а втория клас наричаме *родител*, или *базов клас*, или *суперклас* +- В Java се реализира с ключовата дума `extends` +- Класът-наследник получава достъп до всички `public` и `protected` член-променливи и методи на родителския клас +- Java не поддържа множествено наследяване + +--- + +### Наследяване и method overriding + +- Класът-наследник може да предостави собствена дефиниция на (т.е. да предефинира) методи на родителския клас (*method overriding*) + +--- + +### Наследяване и method overriding + + - Сигнатурата на метода в класа-родител и класа-наследник трябва да е идентична + - Модификаторът за достъп на метод в класа–наследник трябва да съвпада или да разширява модификатора за достъп на метода в родителския клас (но не може да го свива/ограничава) + - Типът на връщаната стойност трябва да е *съвместим* с този на override-вания метод. Съвместим означава идентичен или наследник (за референтните типове) - *return type covariance* + - Методът в класа-наследник е препоръчително да се анотира с опционалната анотация `@Override`. Така компилаторът ще ни помага да не нарушаваме горните правила + +--- + +### Ключовата дума `super` + +- Употребява се за: + - достъпване на член-променливи на родителя + - извикване от конструктор в текущия клас на конструктор в родителския клас + - извикване на произволен метод на родителския клас +- Не нарушава енкапсулацията - през `super` може да достъпим само `public` и `protected` членове на родителския клас +- За разлика от `this`, не се предава като имплицитен параметър на нестатичните методи и конструкторите. JVM-ът знае йерархията от класове по време на изпълнение и може да достъпи елементите на родителския клас директно, без да му трябва референция + +--- + +### Ключовата дума `super` + +```java +public class Student extends Human { + + private int facultyNumber; + + public Student(String name, int facultyNumber) { + super(name); // извикване на родителския конструктор + this.facultyNumber = facultyNumber; + } + + public static void main(String[] args) { + Student ivan = new Student("Ivan", 61786); + ivan.whoAmI(); // наследен от родителя метод + } + +} +``` + +--- + +### Йерархията от класове в Java + +- Всички класове в Java са (преки или косвени) наследници на класа `java.lang.Object` +- Липсата на множествено наследяване означава, че всеки клас има точно един родител (с изключение на един-единствен клас, `java.lang.Object`, който няма родител). +- Следователно, йерархията от класове е дърво, с `java.lang.Object` в корена + +--- + +### `java.lang.Object` + +```java +boolean equals(Object obj) +int hashCode() +String toString() +Object clone() +``` + +--- + +### `equals()` + +- Трябва да го предефинираме, ако сравняваме два обекта за семантична (т.е. смислова) еднаквост, а не по референциите им (т.е. адреса им в паметта) +- Например, две инстанции на клас `Student` смислово са еднакви (отговарят на един и същи студент), ако факултетните им номера са еднакви – без значение дали референциите са еднакви или не + +--- + +### `hashCode()` + +- Трябва да го предефинираме, ако сме предефинирали `equals()` +- При предефинирането на `hashCode()`, ако `equals()` връща `true`, `hashCode`-ът на съответните обекти трябва да е равен +- Ако `hashCode`-ът на два обекта е равен, не е задължително `equals()` да връща `true` + +--- + +### Операторът `instanceof` + +- Използва се за type checking на референтните типове - дали даден обект е инстанция на даден клас + +--- + +### Операторът `instanceof` + +```java +Student ivan = new Student("Ivan", 61786); +Human petar = new Human("Petar"); + +System.out.println(ivan instanceof Student); // true +System.out.println(ivan instanceof Human); // true +System.out.println(petar instanceof Student); // false +System.out.println(petar instanceof Human); // true + +// arrays are reference types +int[] intArr = new int[2]; +System.out.println(intArr instanceof int[]); // true + +// null is not an instance of anything: false for any class +System.out.println(null instanceof AnyClass); + +// true for any non-null ref, because any class extends java.lang.Object +System.out.println(ref instanceof Object); +``` + +--- + +### Pattern matching for `instanceof` (since Java 16) + +```java +// until now +if (obj instanceof String) { + int stringLength = ((String) obj).length(); +} + +// since Java 16 (preview feature in Java 14 & 15) +if (obj instanceof String s) { + int stringLength = s.length(); +} +``` + +--- + +### Ключовата дума `final` + +- в декларация на променлива → прави я константа +- в декларация на метод → методът не може да се override-ва +- в декларация на клас → класът не може да се наследява + +--- + +### Полиморфизъм + +- От гръцки: poly (много) + morphe (форма) +- Дефиниция от биологията - съществуване на морфологично различни индивиди в границите на един вид +- В контекста на ООП, *полиморфизъм* е способността на даден обект да се държи като инстанция на друг клас или като имплементация на друг интерфейс + +--- + +### Полиморфизъм + +- ООП - наследниците на даден клас споделят поведение от родителския клас, но могат да дефинират и собствено поведение +- Всички Java обекти са полиморфични, понеже всеки обект наследява `java.lang.Object` класа + +--- + +### Method overriding vs method overloading + +- *Overriding* - класът-наследник предефинира поведението на класа-родител +- *Overloading* - класът декларира методи с едно и също име и различен брой и/или тип параметри + +--- + +### Runtime полиморфизъм чрез method overriding + +```java +public class Human { + + private String name; + + public Human(String name) { + this.name = name; + } + + public void whoAmI() { + System.out.println("My name is " + name); + } + +} +``` + +--- + +### Runtime полиморфизъм чрез method overriding + +```java +public class Student extends Human { + + private int facultyNumber; + + public Student(String name, int facultyNumber) { + super(name); + this.facultyNumber = facultyNumber; + } + + @Override + public void whoAmI() { + super.whoAmI(); + System.out.println("My faculty number is " + + this.facultyNumber); + } + +} +``` + +--- + +### Compile-time полиморфизъм чрез method overloading + +```java +public class Human { + + public void move() { + System.out.println("I am walking using two legs."); + } + + public void move(String vehicle) { + System.out.println("I move using a " + vehicle); + } + +} + +public class Main { + + public static void main(String[] args) { + Human ivan = new Human(); + ivan.move(); + ivan.move("Car"); + } + +} +``` + +--- + +### Method overriding vs method overloading + +
+ +| | __Overloading__ | __Overriding__ | +| :------------------------------------ | :-------------------- | :----------------------- | +| Кога | Compile-time | Runtime | +| Къде | В същия клас | В класовете - наследници | +| Списък от аргументи | Различен | Идентичен | +| Return type | Може да бъде различен | Съвместим | +| `static`, `private` и `final` методи | Да | Не | +| Свързване (binding) | Статично | Динамично | +| Runtime performance | Better | | + +--- + +### Non-polymorphic code + +```java +Student ivan = new Student("Ivan", 61786); +Human petar = new Student("Petar", 74451); + +Object[] objs = {ivan, petar}; + +for (Object obj : objs) { + + if (obj instanceof Student) { + ((Student) obj).whoAmI(); + } else if (obj instanceof Human) { + ((Human) obj).whoAmI(); + } + +} +``` + +--- + +### Non-polymorphic code + +```java +Student ivan = new Student("Ivan", 61786); +Human petar = new Student("Petar", 74451); + +Object[] objs = {ivan, petar}; + +for (Object obj : objs) { + // instanceof and explicit casts are the "red lights" +* if (obj instanceof Student) { +* ((Student) obj).whoAmI(); +* } else if (obj instanceof Human) { +* ((Human) obj).whoAmI(); +* } + +} +``` + +--- + +### Polymorphic code + +```java +Human[] humans = {ivan, petar}; + +for (Human human : humans) { + human.whoAmI(); +} +``` + +--- + +### Polymorphic code + +```java +Human[] humans = {ivan, petar}; + +for (Human human : humans) { + human.whoAmI(); +} +``` +
+Полиморфният код е не само по-кратък и четим. Помислете, как трябва да се променят двата фрагмента код, ако в бъдеще се появят нови класове – наследници на `Human` + +--- + +### Абстрактни класове + +- Дефинират се с модификатора `abstract` +- Могат да имат методи без имплементация, които се декларират с модификатора `abstract` +- Не са напълно дефинирани (оставят на наследниците си да ги конкретизират/допълнят) + - не могат да се създават обекти от тях +- Един клас не може да бъде едновременно `abstract` и `final` – защо? + +--- + +### Абстрактни класове - пример + +```java +public abstract class Cat { + public void move() { + System.out.println("I am walking on 4 toes."); + } + public void communicate() { + System.out.println("I mew."); + } + public abstract void eat(); +} + +public class DomesticCat extends Cat { + public void eat() { + System.out.println("I eat Whiskas."); + } +} + +public class Leopard extends Cat { + public void eat() { + System.out.println("I eat any prey."); + } +} +``` + +--- + +### Интерфейси + +- Съвкупност от декларации на методи без имплементация +- Описват формално поведение, без да го имплементират +- Може да съдържат `static` `final` член-променливи == константи + +--- + +```java +public interface Animal { + void move(); + void communicate(); +} +public class Human implements Animal { + private String name; + public Human(String name) { + this.name = name; + } + public void move() { + System.out.println("I am walking using two legs"); + } + public void communicate() { + System.out.println("I speak"); + } +} +public class Cat implements Animal { + public void move() { + System.out.println("I am walking using 4 toes"); + } + public void communicate() { + System.out.println("I mew"); + } +} +``` + +--- + +### Методи на интерфейсите + +- Методите на интерфейсите са `public` и `abstract` по подразбиране +- Модификаторите `public` и `abstract` (заедно или поотделно) могат да бъдат указани и експлицитно + - дали да бъдат експлицитно указани, е въпрос на стил - но е добре да сме консистентни +- Тъй като методите са абстрактни, не могат да бъдат декларирани като `final` + +--- + +### Интерфейси и наследяване + +- Интерфейсите могат да се наследяват +- Един интерфейс може да наследява множество интерфейси + +--- + +### Интерфейсите и имплементаците им + +- Интерфейсите не могат да се инстанцират +- Можем да инстанцираме (конкретни) класове, които ги имплементират +- Можем да присвояваме инстанция на клас на променлива от тип интерфейс, който класът имплементира +- Можем да проверяваме с `instanceof` дали клас имплементира даден интерфейс +- Един клас може да имплементира множество интерфейси + +--- + +### Интерфейси и имплементациите им + +- Ако даден клас декларира, че имплементира интерфейс, той трябва или + - да даде дефиниции на *всичките* му методи, или + - да бъде деклариран като абстрактен +- Като следствие, ако променим сигнатурата на метод(и) на интерфейса, или ако добавим нов(и) метод(и), трябва да променим и всички имплементиращи интерфейса класове +- Това често е проблем, а понякога е и невъзможно (нямаме контрол върху всички имплементации) + +--- + +### Default методи в интерфейсите (от Java 8) + +- Default-ен метод в интерфейс е метод, който + - има имплементация + - има модификатора `default` в декларацията си +- Имплементиращите класове имплицитно ползват default-ната имплементация на методите, но могат и да я предефинират + +--- + +### Default методи в интерфейсите (от Java 8) + +- Клас може да имплементира произволен брой интерфейси +- Ако два или повече от тях съдържат `default` метод с еднаква сигнатура, класът трябва задължително да предефинира този метод +- В предефинирания метод може експлицитно да се укаже, default-ната имплементация от кой родителски интерфейс да се ползва. В този случай, синтаксисът е, `<имеНаИнтерфейс>.super.<имеНаDefaultМетод>()` + +--- + +### Default методи в интерфейсите (от Java 8) + + +```java +public interface OptimisticLockable { + default boolean isLocked() { + return false; + } +} +public interface PessimisticLockable { + default boolean isLocked() { + return true; + } +} +public class Door implements OptimisticLockable, PessimisticLockable { + + // We will get a compile-time error, if we don't override the isLocked() method here: + // - "Door inherits unrelated defaults for isLocked() from types + // OptimisticLockable and PessimisticOldLockable" + @Override + public boolean isLocked() { + return OptimisticLockable.super.isLocked(); + } +} +``` + +--- + +### Статични методи в интерфейсите (от Java 8) + +- От Java 8, интерфейсите могат да съдържат и статични методи с имплементация +- Една класическа употреба е, за *factory* методи (ще говорим за тях в лекцията за design patterns) + +--- + +### Private методи в интерфейсите (от Java 9) + +- От Java 9, интерфейсите могат да съдържат и `private` методи с имплементация +- Изполват се, когато в интерфейса има два ли повече default-ни или статични метода, чиято имплементация частично се дублира + - тогава изнасяме повтарящия се код в `private` метод, за да предотвратим code duplication + +--- + +### Интерфейсите - обобщение + +- Интерфейсите могат да съдържат + - Публични, абстрактни методи без имплементация + - `static` `final` член-променливи == константи + - `default` и `static` методи с имплементация (от Java 8) + - `private` методи (от Java 9) + +--- + +### Интересни частни случаи на интерфейси + +- Интерфейс, който + - не съдържа нито един метод, се нарича *маркерен* + - има точно един публичен абстрактен метод, се нарича *функционален* + +--- + +### Абстракция + +- Абстракция означава, моделирайки в обектно-ориентиран език за програмиране обекти от реалния или виртуалния свят, да се ограничим само до съществените им за конкретната задача характеристики и да се абстрахираме (пропуснем) в модела несъществените или нерелевантни за задачата + - Пример: моделирайки студент, да го характеризираме само с име и факултетен номер, абстрахирайки се от всички други характеристики на студента в реалния свят (напр. цвят на очите) + +--- + +### Абстракция + +- Абстракция също означава да работим с нещо, което знаем как да използваме, без да знаем как работи вътрешно. Всяка конкретна имплементация на поведение е скрита в своя обект, за външния свят е видимо само поведението (т.е. интерфейсът) +- Принципът за абстракция се постига в Java чрез интерфейси и абстрактни класове + +--- + +## Въпроси? + +.font-xl[.ri-github-fill.icon-inline[[fmi/java-course](https://github.com/fmi/java-course)]] + +.font-xl[.ri-youtube-fill.icon-inline[[MJT2024](https://www.youtube.com/playlist?list=PLew34f6r0Pxyldqe31Txob2V3M3m1MKCn)]] diff --git a/README.md b/README.md index e0f0b3cc..c121bc77 100644 --- a/README.md +++ b/README.md @@ -9,6 +9,7 @@ | # | Тема | Лекция | Видео | Дата | Упражение | Видео | Дата | | - | :--- | :----- | :---- | :--- | :-------- | :---- | :--- | | 1 | Въведение в Java | [слайдове](https://fmi.github.io/java-course/01-intro-to-java/lecture/slides.html) | [![Video](web/images/mjt-on-youtube.png)](https://youtu.be/X1bh5oAggsQ) | 09.10 | [задача](https://github.com/fmi/java-course/tree/master/01-intro-to-java/lab) | [![Video](web/images/mjt-on-youtube.png)](https://youtu.be/Bs3v6fr_qHk) | 12.10 | +| 2 | ООП с Java (част I) | [слайдове](https://fmi.github.io/java-course/02-oop-in-java-i/lecture/slides.html) | | 16.10 | | | 19.10 | ### Материали от предходни издания