Об'єктно-орієнтовне програмування


Об'єктно-орієнтовне програмування

Об'єктне (модульне) програмування

Процедурна парадигма віддала належне алгоритмічній компоненті програмування. Але з ростом обсягу програм і складності даних з'явилася нова проблема структурної організації даних, найбільш ємко висловлена Віртовською формулою “алгоритми + структури даних = програми”.

 

Поняття модуля як абстракції даних було вперше запропоноване Парнасом у 1972 році, правда на той час уже існувала мова програмування Симула 67, в якій використовувалася парадигма об'єктів. У найбільш повному виді поняття абстракції даних було реалізоване в мові програмування Модула-2.

 

Головна ідея полягає в забезпеченні доступу до даних, не залежному від їх конкретного представлення. Самі дані і програми їх обробки вбудовуються (інкапсулюються) в окремій одиниці програми. Ось простий приклад, який показує, як складність обчислень може перетікати у складність даних: Обчислення математичної функції, скажімо, квадратного кореня, можна виконати, обчислюючи границю відповідної послідовності, наприклад такої:

 

Цей же квадратний корінь можна знайти у відповідному рідку чотиризначних математичних таблиць Брадіса. У першому випадку вся складність зосереджена в алгоритмі, який необхідно було придумати і запрограмувати (що ми й зробили у наведеному вище прикладі програми на Паскалі). У другому — в структурах даних, тобто в таблицях, які професор В.М.Брадіс повинен був попередньо розрахувати.

 

Ось приклад тексту в Модулі 2, який дає певне уявлення про поділ модуля на дві частини — визначення і реалізацію:

 

definition module Months;

type Month=

(jan, feb, mch, apr, may, jun,

jul, aug, sep, oct, nov, dec);

procedure length(m: Month) : Cardinal;

end Month;

 

implementation module Month;

var

len: array Month of Cardinal;

procedure length(m: Month) : Cardinal;

begin

return len[m];

end length;

begin

len[jan]:=31; len[feb]:=28;

len[mch]:=31; len[apr]:=30;

len[may]:=31; len[jun]:=30;

len[jul]:=31; len[aug]:=31;

len[sep]:=30; len[oct]:=31;

len[nov]:=30; len[dec]:=31;

end Month.

 

 

Об'єктно-орієнтована парадигма наділила класи ієрархією. Об'єктно-орієнтоване програмування за метафорою Б.Страуструпа, автора С++ — однієї з найпопулярніших мов об'єктно-орієнтованого програмування, — це високоінтелектуальний синонім доброго програмування. Дійсно, нові парадигми програмування з'являються не так часто, не частіше однієї в десятиліття. Той факт, що об'єктно-орієнтована парадигма успішно використовується протягом 20 років, сам по собі служить вагомим підтвердженням її життєздатності.

 

Дійсно, алгоритми, реалізовані в процедурному програмуванні, надто конкретні. Будь-яка модифікація — це вже новий алгоритм і таким чином кількість процедур і функцій, що знаходяться у вжитку, надмірно зростає. Модульне програмування групує алгоритми в модулі, одночасно інкапсулюючи структури даних. Тепер залишається зробити наступний крок — побудувати ієрархію модулів або класів.

 

Таких ієрархій може бути дві. Перша з них — бути частиною чогось. Наприклад, грань є частиною многогранника, ребро — частиною грані, вершина — частиною ребра. Інша ієрархія — бути узагальненням або конкретизацією. Наприклад, овал і многокутник служать конкретизацією плоскої фігури, коло — конкретизацією овалу, чотирикутник — конкретизацією многокутника, подальшими конкретизаціями чотирикутника можуть служити паралелограм, прямокутник, ромб, квадрат. Той факт, що квадрат, ромб, прямокутник є повноцінними паралелограмами дозволяє їм користуватися усіма програмними засобами, створеними для паралелограма, паралелограм в свою чергу є повноцінним чотирикутником і так далі. Цей принцип, відомий під назвою reusable знову вживаний — став одним з найважливіших досягнень об'єктно-орієнтованої парадигми. Знову вживаючи вже існуюче програмне забезпечення в більш конкретизованих умовах, ми дописуємо лише ту його частину, яка стосується особливостей наявної конкретизації. Цей принцип дістав назву programming by difference або дописування програм .

 

І, нарешті, об'єктно-орієнтована парадигма доводить до логічної завершеності принцип моделювання реального світу, а точніше тієї його частини, абстракцією якої служить програма. При цьому підході програма складається з об'єктів, що відповідають реальним поняттям або предметам. Виконання програми зводиться до взаємодії об'єктів, яке служить абстракцією реальної взаємодії їх прототипів. Все це разом забезпечило об'єктно-орієнтованому підходу беззаперечне лідерство в галузі розробки програм.

 

Сьогодні в сімействі мов об'єктно-орієнтованого програмування три найбільш відомих представника: С++,

Java і C # ( читається Сі шарп ). С++ і сьогодні залишається визнаним лідерів в розробці великих і складних програмних систем.

Java і C # виросли з С++. Вони мають свою сферу застосування в розподіленому програмуванні і будуть вивчатися нами пізніше.

 

Ще одна перевага С++ — його мультипарадигменність. С++ містить в собі мову С (з деякими застереженнями), а тому, природно, підтримує процедурну парадигму. Ось приклад функції для обчислення квадратного кореня в С/С++:

 

double root (double x, double eps)

{

double s=0.5*x;

double t;

do

{

t=s;

s=(s+x/s)*0.5;

}

while ((fabs(s-t)/s)>eps);

return s;

};

 

 

С++ також підтримує традиційні для модульного програмування механізми абстракції даних, доповнені можливостями об’єктно-орієнтованої парадигми. Ось якого виду набуде наведений вище приклад із Модули 2

 

enum month {jan=1, feb, mch, apr, may, jun,

jul, aug, sep, oct, nov, dec};

struct Month

{

inline int length(){return len[mon-1];}

Month(month n):mon(n){};

private:

month mon;

static int len[12];

};

int Month::len[12] {31,28,31,30,31,30,31,31,30,31,30,31};

 

Тепер Month — це повноцінний тип даних, який можна вживати, нарівні зі стандартними, у визначенні змінних, наприклад,

Month theMonth = may;

int i = theMonth.length();

 

 

Як ми побачимо далі, можна навіть довизначити арифметичні операції, наприклад, операцію збільшення місяця на ціле число, що дозволить писати вирази виду theMonth + 5. І, нарешті, С++ реалізує парадигму узагальнених функцій і параметризованих типів, але про це далі.