Клас (програмиране)

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

Класът е една от характеристиките на обектно ориентираното програмиране. Това е съвкупност от променливи и функции, които са обвързани в логическа структура и работят заедно.[1] Класът служи като модел за представяне на реални обекти и софтуерни обекти, описвайки атрибути (свойства) и методи (поведение) на обектите.

Взаимовръзки между класовете[редактиране | редактиране на кода]

Като допълнение към дизайна на самостоятелните класове, езиците за програмиране могат да поддържат по-сложен дизайн въз основа на връзки между класовете. Най-често срещаните типове междукласови връзки са композиционни и йерархични.

Композиционна[редактиране | редактиране на кода]

Класовете могат да бъдат съставени от други класове, осъществявайки по този начин композиционна връзка между обхващащият клас и неговите вградени класове. Композиционната връзка между класове също е известна като „има“ връзка. Например, клас „Автомобил“ може да бъде съставен от и да включва клас „Двигател“. Следователно, Колата има Двигател. Ако обхващащият обект включва компонентни инстанции по стойност, то компонентите и обхващащият ги обект имат еднаква продължителност на живот. Ако компонентите са включени по референция обаче, то продължителността им на живот може да бъде различна.

Йерархична[редактиране | редактиране на кода]

Класове могат да произлизат от един или повече вече съществуващи класове, формирайки по този начин йерархична взаимовръзка между първоизточниците (базови класове, бащини класове или супер-класове) и произлизащите класове (наследствени класове, суб-класове). Взаимовръзката между наследственият клас и базовият клас е широко известна, като „е“ връзка. Например, клас „Бутон“ може да произлиза от клас „Контрола“. Следователно, всеки Бутон е Контрола. Структурните и поведенчески членове на бащиния клас се унаследяват от наследствения клас. Наследствените класове могат да имат в себе си дефинирани допълнителни структурни членове (полета данни) и/или поведенчески членове (методи), в допълнение към наследените такива. Също така в някои езици за програмиране е позволено, суб-класовете да отменят и/или предефинират наследени методи.

Не всички езици позволяват множествено наследяване. Например Java позволява даден клас да имплементира множество интерфейси, но да наследява от само един клас. В случай, че множественото наследяване е позволено, йерархията е тип насочен ацикличен граф (или НАГ за по-кратко), в противен случай е тип дърво. В йерархията класовете играят ролята на възли, а унаследяванията – на връзки. Нивата на тази йерархия се наричат слоеве или слоеве на абстракция (нива на абстракция).

Наследственост[редактиране | редактиране на кода]

Въпреки че клас-ориентираните езици са често приемани, че поддържат наследяване, то не е присъща част от концепцията за класове. Някой езици, често сочени като „обектно ориентирани езици“, поддържат класове, но не поддържат наследяване. Примери за обектно ориентирани езици включват по-ранните версии на Visual Basic.

Асоцииране[редактиране | редактиране на кода]

В обектно ориентирания анализ и в UML (Унифициран език за моделиране), асоциация между два класа представлява сътрудничество между класовете или техните инстанции. Асоциациите имат посока; например, бинарно-ориентираната асоциация между два класа означава, че двата класа са наясно с връзката си. Асоциациите могат да бъдат обозначени в зависимост от тяхното име или цел.

Асоциативна роля е даден край на асоциация и описва ролята на съответния клас. Например ролята на „абонат“ описва начина, по който инстанциите от класа „Човек“, участват в „абониран за“ връзка с класа „Списание“. Също така „Списание“ има „списания с абонамент“ роля със същата връзка. Множеството от асоциативни връзки описва колко инстанции взаимодействат с всяка инстанция от друг клас от асоциацията. Често срещаните множества са „0..1“, „1..1“, „1..*“ и „0..*“ където „*“ означава какъвто и да е брой на инстанциите.

Видове класове[редактиране | редактиране на кода]

Има много различни категории класове; все пак тези категории не са задължително разделени класове в отделни дялове.

Абстрактни и конкретни[редактиране | редактиране на кода]

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

Повечето обектно ориентирани езици за програмиране позволяват на програмистите да уточняват кои класове се смятат за абстрактни и няма да позволят на такива да бъдат инстанцирани. Например в Java и PHP, ключовата дума abstract (абстрактен) се използва. В C++, абстрактен клас е такъв имащ поне един абстрактен метод зададен чрез съответния синтаксис в езика (чиста виртуална функция в C++ езика).

Клас състоящ се само от виртуални методи се нарича Чисто Абстрактен Основен Клас (Pure ABC) в C++ и също е известен като интерфейс от потребителите на езика. Други езици, особено Java и C#, поддържат вариант на абстрактни класове, наричани interface (интерфейс) чрез ключовата дума в езика. В тези езици множественото наследяване не е разрешено, но класа може да имплементира много интерфейси. Интерфейсът може да съдържа публично достъпни методи или пропъртита.

Конкретния клас (concrete class) е такъв, който може да се инстанцира, противоположно на абстрактните класове, които не могат.

Локални и вмъкнати[редактиране | редактиране на кода]

При някои езици, класовете могат да се декларират в друг обхват (scope) освен в глобалния. Има много видове такива класове.

Вътрешен/вмъкнат (inner) клас е такъв, който се дефинира в друг клас. Взаимовръзката между вътрешния клас и този, който го обгръща може да се разглежда като друг тип класова свързване. Вътрешния клас обикновено не е нито асоцииран с инстанциите на обгръщащия клас, нито е инстанцииран заедно с него. В зависимост от езика е възможно или не да се извиква вътрешния клас от място извън обгръщащия. Сходна концепция притежават и вътрешните типове (inner types), също известни като вътрешни типове данни или вложени типове, което е генерализация на концепцията за вътрешни класове. C++ е пример за език, който поддържа и вътрешни класове, и вътрешни типове (чрез typedef декларацията).

Друг тип е локалния клас, който е клас дефиниран вътре в процедура или функция. Това ограничава достъпа до името на класа само в обхвата където класа е зададен. В зависимост от семантичните правила на езика може да има допълнителни ограничения на локалните класове в сравнение с нелокалните такива. Едно често срещано ограничение е забраната на локалните класове да имат достъп до локалните променливи на обгръщащата ги функция. Например в C++ локален клас може да се обръща към статични променливи декларирани в обгръщащата функция, но не може да използва останалите променливи на функцията.

Метаклас[редактиране | редактиране на кода]

Метакласовете са класове чиито инстанции са класове. Метакласовете описват обща структура на колекция от класове и могат да имплементират дизайн модел (design pattern) или да опишат определени видове класове. Метакласовете са често използвани за описване на фреймуърци (frameworks).

При някои езици, като Python, Ruby или Smalltalk, класа е също и обект; поради тази причина всеки клас е инстанция на уникален метаклас, който е вграден в езика. Например в Objective-C, всеки обект и клас са инстанция на NSObject. Например така наречената Common Lisp Object система (CLOS) осигурява метаобектови протоколи (metaobject protocols – MOPs) за да имплементира тези класове и метакласове.

Ненаследими[редактиране | редактиране на кода]

Ненаследимите класове (класове без подкласове) позволяват на програмистите да създават класове и архитектури от класове, които след дадено ниво да не могат да се разклоняват повече.(Самостоятелните класове също може да се третират като ненаследими, защото не позволяват да се създават йерархични структури с тях). За сравнение абстрактните класове предполагат, насърчават и дори изискват разклоняване (създаване на подкласове), за да се използват въобще. Ненаследимите класове обаче са изрично фиксирани.

Ненаследим клас се декларира с sealed в C# или final в Java.

Пример: В Java класът String е дефиниран като final.

Ненаследимите класове позволяват на компилатора (в езиците ползващи компилатор) да направи оптимизации, които не са достъпни за наследимите класове.

Частични[редактиране | редактиране на кода]

В езиците поддържащи тази опция, частичните класове са класове, чиято дефиниция може да се раздели в няколко части на различни места в сорс кода или в отделни файлове. Тези части се събират по време на компилация, което позволява изходния код да е идентичен с този на нечастичните (целите) класове.

Основната причина за въвеждането на частични класове е улесняване разработката и имплементирането на генератори на код, например графични/визуални дизайнери. Без частичните класове, генераторите трябва да управляват и вмъкват генерирания от тях код на различни места в оригиналния сорс код. Това поражда редица проблеми както с ефективността на компилатора така и с риск от грешки и повреждане на крайния сорс код. За да се избегне това, генераторите създават своя код в отделни файлове или в грубо дефинирани частични класове и компилаторът минава през фаза на „пред-компилация“ (обединяване на сегментите) преди да продължи с нормалната си работа.

Други ползи от употребата на частични класове са:

  • Позволява да се отделя интерфейса на класа от работния му код
  • Лесна навигация в големи класове с помощта на редактор
  • Позволява разделяне на модули, подобно на аспектно-ориентираното програмиране, но без употребата на допълнителни инструменти
  • Позволява няколко специалиста да работят едновременно по един клас без нуждата от последващо обединяване на техния код в един файл.

Частичните класове съществуват от доста време в Smalltalk под името Class Extensions. Майкрософт въвежда частичните класове в .NET framework 2, както за C# 2.0 така и за Visual Basic 2005. WinRT също поддържа частични класове.

Неинстантни[редактиране | редактиране на кода]

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

Пример: в C#, клас обозначен със „static“, не може да се инстанциира, може да съдържа само статични членове (полета, методи, други), няма конструктор и е фиксиран/запечатън.

Безименни / анонимни[редактиране | редактиране на кода]

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

Ползи[редактиране | редактиране на кода]

Компютърните програми обикновено представят модел на реалния свят или някакъв абстрактен свят (например домейн). Понеже всеки клас моделира отделна концепция, употребата на класове позволява по естествен начин да се моделира заобикалящият ни свят. Всеки клас в модела може да се разглежда като съществително, методите на този клас – като глаголи, които се отнасят до тези съществителни. Например една бизнес система може да се моделира с помощта на класове като „Клиент“, „Продукт“, „Служител“, „Фактура“, „Работа“ и т.н. Класът „Фактура“ може да има методи като „Създай“, „Отпечатай“ или „Изпрати“. Класът „Работа“ може да се „извърши“ (метод) или „отмени“ (друг метод). Ако програмата може да моделира и опише реалността акуратно, то тя може да предостави на потребителите ценна информация за тази система и нейните обекти. Класовете позволяват ясни връзки между модела и реалността, което прави лесно създаването, поддържането, промяната и разбирането на модела. Класовете също така позволяват повече контрол върху сложността на подобни модели (опростяване, прегледност).

Класовете ускоряват разработката на програми, като намаляват повторението на идентичен код, улесняват тестовете и отстраняването на грешки. Ако един клас е щателно тестван и е доказано чист от грешки (бъгове), то употребата му ще подобри качеството на крайния код за разлика от употребата на прясно написан код или код сглобен по copy/paste модела. Освен това ефективното преизползване на класове означава, че ако е допусната грешка, то ще трябва да се редактира само един клас, а не няколко различни сегмента от кода.

В допълнение класовете може да се асоциират или наследяват взаимно, което опростява модела на взаимосвързаност. Така по-лесно може да се проследи йерархията на обектите, връзките между тях и модела им на взаимодействие. Също така се намалява нужния код – ако например два класа споделят еднакви атрибути, но единия има допълнителни атрибути (описва частен случай), то може единия клас да се дефинира като подклас на другия и съвместните им атрибути да се запишат само веднъж. Като цяло добре изградена рамка от класове улеснява навигацията, разбирането и работата с компютърни програми.

  Тази страница частично или изцяло представлява превод на страницата Class (computer programming) в Уикипедия на английски. Оригиналният текст, както и този превод, са защитени от Лиценза „Криейтив Комънс – Признание – Споделяне на споделеното“, а за съдържание, създадено преди юни 2009 година – от Лиценза за свободна документация на ГНУ. Прегледайте историята на редакциите на оригиналната страница, както и на преводната страница, за да видите списъка на съавторите. ​

ВАЖНО: Този шаблон се отнася единствено до авторските права върху съдържанието на статията. Добавянето му не отменя изискването да се посочват конкретни източници на твърденията, които да бъдат благонадеждни.​

Източници[редактиране | редактиране на кода]

  1. Наков, Светлин и др. Въведение в програмирането с Java. първо издание. Велико Търново, Фабер, 2009. ISBN 978-954-400-055-4. с. 316. Посетен на 2024-01-29. класът е план или шаблон, който описва природата на нещо (някакъв обект)