Обяснение за ООП?

+9 гласа
3,498 прегледа
попитан 2016 юни 12 от VeskoNikolov (1,620 точки)
Здравейте,

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

Този въпрос е по-скоро на тема програмиране като цяло, но го пиша в категорията за Java, понеже тя е обектно-ориентиран език.

2 отговори

+4 гласа
отговорени 2016 юни 12 от Warrior (1,720 точки)

В първия момент, когато учех програмиране пишех процедурно на PHP. Не познавах програмисти и нямаше кой да ме насочи към по-добрия подход на използване на езика. Трябваше сам да открия силата на ООП. Още тогава знаех, че ще започна да го изучавам, но изпитвах някаквъв странен "страх", че е много сложно. Още когато прочетох първите няколко страници за въведението в OOP си дадох сметка, че това е нещо, което е изключително логично, удобно за ползване и от този момент натам, нямаше да пиша повече процедурно. Точно така и стана.

Какво ти дава ООП? Дава ти възможност да работиш с обекти, които обекти имплементират реални такива от нашия свят. Или казано иначе, всяко нещо от нашия материален свят може да се представи като обект с някакви характеристики (пропъртита), действия (методи) и ти да извършваш операции над него. 

Главната причина да използваме ООП е, че принципите му са изключително полезни и удобни за работа. Фундаменталните му концепции са:

  • Наследяване (inheritance). То ти дава възможност да преизползваш и extend-неш вече създаден код, като имаш възможността да доразвиеш логиката му, без да я нарушаваш в базовия клас. Изключително мощно нещо.
  • Капсулиране (encapsulation). Нещо, което е много удобно за използване. Веднага ти давам много скорошен пример. Наложи ми се да пиша логика, която импортира данни от Google Spredsheet документи. Самото свързване с API-то на Google не е никак просто. Подават се едни сертификати, предварително генерирани, правят се едни обръщения към даден техен URL, гледа се отговора и още няколко дълги за писане операции. Веднага си го капсулирах. Направих си един мой клас (така наречения wrapper), който се грижи за това да прави всички сложнотии, свързани с аутентикацията в Google. А аз, за да го използвам и да се свържа с тяхното API викам само нещо от рода на GoogleSpredsheet.Authenticate() и това е, той се оправя сам. Вътре се грижи и си прави всички гореописани неща. Това е капсулация на логика.
  • Полиморфизъм (polymorphism). Позволява ти да извикваш даден метод на различни по тип класове, като е достатъчно да знаеш само, че тези класове имплементират дадения метод. Това става посредством наследяването от всички на деден interface. Ето ти пример. Имаш колекция от устройства, които възпроизвеждат музика/видео. Знаеш, че всички плейъри имат метод "Play" (защото всичките имплементират interface, който дефинира метода "Play") и като го извикаш пускат даденото нещо. Ти не се интересуваш как точно го правят, как четат данните и как ги възпроизвеждат, но знаеш, че го имплементират. Тогава съвсем спокойно можеш да си направиш колекция от плейъри, например: стандартното видео с VHS касети, аудио касетофон и MP3 плайър. Можеш да ги завъртиш в един цикъл и на всеки един от тях да извикаш метода "Play". Тогава всеки един тип, по неговия си начин ще изпълни командата да пусне (play-не) даденото нещо. Мисли го от абстрактна гледна точка, не се вкарвай в детайли как точно ще го изпълни.
  • Абстракция (abstraction). Да държим дадени методи на абстрактно ниво е много полезно защото това позволява нашият метод да работи с много на брой типове, а не с конкретен. Ето ти пример: ако методът ти очаква да получи като параметър array от int, то на него можеш да подадеш само и единствено този тип данни. Но ако методът ти очаква да получи IEnumerable<int>, то тогава той е по-абстрактен и може да получи всеки един тип, който имплементира този interface. Това значи, че вече можеш да подаваш както List<int> и int[], така и твои типове, които имплементират този интерфейс.

Опитах се съвсем накратко да ти обясня основните концепции на ООП. Истинската сила идва, когато всички те се кобинират и използват като едно цяло. 

Много полезно би било да погледнеш също и SOLID принципте: http://www.c-sharpcorner.com/UploadFile/damubetha/solid-principles-in-C-Sharp/ които са супер мощни средства в програмирането и осигуряват една стабилна архитектура на приложението ти. Сигурен съм, че можеш да си ги намериш и описани на Java.

коментиран 2016 юни 12 от Warrior (1,720 точки)
Между другото, наскоро в университета правихме задача свързана с полиморфизъм. Там беше с геометрични фигури. Имаш една базова абстрактна, която дефинира периметъра и много нейни наследници, които override-ват този периметър и го имплементират по подходящия за тях начин.
Там можеш да видиш няколко от принципите споменати горе в действие. Дай си имейла и ще ти го пратя. Даже го имам писано на Java.
+1 глас
отговорени 2016 юни 13 от Антон Яначков (490 точки)
редактиран 2016 юни 13 от Антон Яначков
Казваш че си чел много и аз ти вярвам. Не си срещнал добро обяснение и това е толкова логично. Древните мъдреци казват, че знаниетое не това което са ти казали и не е това което си прочел или чул някъде. Според тях знанието е само това, което си ПРЕЖИВЯЛ, защото само това което си преживял за теб е истина и само то конкретно за теб не подлежи на съмнение. Твоето знание е различно от моето и е различно от всички, които се опитват да обясняват какво е обектно ориентирано програмиране. Ако търсиш действително отговор на този въпрос трябва да престанеш да четеш и да отделиш време да пишеш. Само така за кратко време ще изградиш своето знание по конкретния въпрос. Нямам предвид да пишеш статии, а да пишеш програми, на който и да е обектно ориентиран език. Аз мога да споделя моето знание, но то ще бъде различно от това което си чел. Това само ще възбуди негодувание в теб, защото за сетен път ще прочетеш нещо което няма да съвпадне с прочетеното от теб до момента. Всяко дете проговаря на майчиния си език на втората или трета година от своя живот, научавайки език без да е прочело и една книга. Убеден съм, че и ти си научил български език, без да си чел мнения във форумите как се се говори на български език. Не ти е било изобщо необходимо да четеш,за да се научиш да говориш. Просто си опитвал, грешал си и пак си опитвал до като познанията ти по езика са станали на такова ниво, че си започнал свободно да разбираш всичко, което чуваш. Ти си получил своето знание благодарение на опита, който си натрупал. Разбирането на ООП е абсолютно аналогично. За начинаещия програмист обектите са като простите думи  в речника на двугодишното дете. С тях може да се постигне конкретна цел, ако ги използваш за да сглобиш една фраза. В неговите очи докосването до обектите е значимо събитие,защо само казваш ИСКАМ и вече поучаваш това, което искаш. По големите деца вече усъвършенстват речника си, което означава, че познават повече различни обекти и започват по-умело да си служат с тях. Тяхната представа за света се променя, променя се и отношението им към самите обекти. Заповат да осъзнават, че света е много по-разнообразен и определено по сложен. Идва време и дето тръгва на училище. Започват да го принуждават да събира и вади прости числа. В този момент то разбира,че можеш да виждаж 1+1, но на този сбор от обекти трябва да казваш 2. Малкият човешки мозък се учи да комбинира обекти и запова да преоткрива всичко отначало. Тази цикличност се повтаря многократно в човешкия живот дори когато детето се е превърнало вече в смръщен професор, който пише интеграл след интеграл по черната дъска. Младите студенти гледат как смръщения професор с лекота пише сложни математични формулировки, като обяснява, че градиента на дивергенцията точно описвало процеса, за койтоиде реч. Излиза,че има огромна разлика в представите за света на обектите във всяка една възраст на човека. Ти намираш по книгите различни писания за ООП, като дълбоко усещаш, че не е казано достаъчно ясно и просто. Така и трябва да бъде. Няма как да бъде по-различно. Писанията са сътворени от различни хора на различно ниво в своето развитие и е малко вероятно да попаднеш на книга написана от човек, който е на точно твоето ниво. Но дори и да попаднеш на такава книга, какво би научил ти от този автор, ако той е на твоето ниво. Виждаш ли затворения кръг. Ето защо няма как да разбереш какво е ООП, чрез четене, защото то не е може да се опише така, че да стане ясно на средно статистическия Пешо. Ако средно статистическият Пешо никога не се е занивал с програмиране, то той е на нивото на двегодишно дете и тепърва му предстои да научи майчиния си език.

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

Ето прост пример за обект ориентиран към широката публика, а не към теб. Все пак ти си изчел много книги.

<input type='text'>

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