Clasa (programare)

Versiunea actuală a paginii nu a fost încă revizuită de colaboratori experimentați și poate diferi semnificativ de versiunea revizuită la 18 iunie 2015; verificările necesită 43 de modificări .

Clasă  - în programarea orientată pe obiecte , un model pentru crearea de obiecte de un anumit tip , descrierea structurii acestora (un set de câmpuri și starea lor inițială) și definirea algoritmilor (funcții sau metode ) pentru lucrul cu aceste obiecte.

Cu alte cuvinte, o clasă servește ca vehicul pentru introducerea unor tipuri de date abstracte într-un proiect software. Alți descriptori ai tipurilor de date abstracte - metaclase , interfețe , structuri , enumerații - sunt caracterizați prin unele dintre propriile caracteristici. Esența diferenței dintre clase este că atunci când se specifică un tip de date, o clasă definește simultan atât o interfață, cât și o implementare pentru toate instanțele sale (adică obiectele), deci apelarea metodei constructorului este obligatorie.

Clasa este unul dintre conceptele cheie în POO , dar există și limbaje fără clasă orientate pe obiecte, cum ar fi Self , JavaScript , Lua , (consultați Programarea prototipurilor pentru mai multe detalii ).

În practică, programarea orientată pe obiecte se reduce la crearea unui număr de clase, inclusiv o interfață și o implementare, și apoi utilizarea acestora. O reprezentare grafică a unui număr de clase și a relațiilor dintre ele se numește diagramă de clase . În timpul dezvoltării sale, abordarea orientată pe obiecte a acumulat o mulțime de recomandări ( modeluri ) pentru crearea claselor și a ierarhiilor de clase .

Ideea claselor a venit din munca de bază de cunoștințe relevante pentru cercetarea inteligenței artificiale. Clasificările folosite de om în zoologie, botanică, chimie, piese de mașini poartă ideea de bază că orice lucru poate fi întotdeauna reprezentat ca un caz special al unui concept mai general. Un anumit mar este un mar in general, un mar in general si orice mar in general este un fruct. (Merele și perele sunt un exemplu comun de clase în tutorialele de programare orientată pe obiecte.)

Peste tot mai jos, cuvintele „clasă”, „ obiect ”, „ interfață ” și „ struct ” vor fi folosite în semnificațiile lor speciale date în POO.

Clase și obiecte, conceptul de instanță de clasă, conceptul de membri ai clasei

Într-un program orientat pe obiecte care utilizează clase, fiecare obiect este o „ instanță ” a unei anumite clase și nu sunt furnizate alte obiecte. Adică, „o instanță a unei clase ” în acest caz nu înseamnă „un exemplu de o clasă” sau „o singură clasă”, ci „un obiect al cărui tip este o clasă”. În același timp, în diferite limbaje de programare, existența altor tipuri de date este permisă sau nu, ale căror instanțe nu sunt obiecte (adică limbajul determină dacă lucruri precum numerele, tablourile și pointerii sunt obiecte sau nu și, în consecință, dacă există clase precum „număr”, „matrice” sau „pointer” din care fiecare anumit număr, matrice sau pointer ar fi o instanță).

De exemplu, tipul de date abstracte „line of text” poate fi proiectat ca o clasă, iar apoi toate liniile de text din program vor fi obiecte - instanțe ale clasei „line of text”.

Când utilizați clase, toate elementele codului programului, cum ar fi variabilele, constantele, metodele, procedurile și funcțiile, pot aparține (și în multe limbi trebuie să aparțină) uneia sau alteia clase. Clasa în sine este definită în cele din urmă ca o listă a membrilor săi , și anume câmpuri ( proprietăți ) și metode/funcții/proceduri . În funcție de limbajul de programare, la această listă pot fi adăugate constante, atribute și definiții externe.

Ca și structurile, clasele pot defini câmpuri, adică variabile care aparțin fie direct clasei în sine (statice), fie instanțelor clasei (obișnuite). Câmpurile statice există într-o singură instanță pentru întregul program (sau, într-o versiune mai complexă, într-o singură instanță per proces sau per fir / fir ). Câmpurile obișnuite sunt create o copie pentru fiecare obiect specific - o instanță a clasei. De exemplu, numărul total de linii de text create în program în timpul funcționării acestuia va fi un câmp static al clasei „linie de text”. Și o anumită matrice de caractere ale unui șir va fi un câmp obișnuit al unei instanțe a clasei "șir de text", la fel cum variabila "nume" de tipul "șir de text" va fi un câmp obișnuit al fiecărei instanțe specifice. din clasa „persoană”.

În POO, atunci când se utilizează clase, tot codul de program executabil (algoritmii) va fi prezentat sub formă de așa-numitele „metode”, „funcții” sau „proceduri”, care corespunde programării structurate convenționale , dar acum pot (și în multe limbi trebuie să aparțină uneia sau altei clase. De exemplu, dacă este posibil, clasa „șir de text” va conține toate metodele/funcțiile/procedurile de bază concepute pentru a funcționa cu un șir de text, cum ar fi căutarea într-un șir, tăierea unei părți a unui șir etc.

Ca și câmpurile, codul sub formă de metode/funcții/proceduri aparținând unei clase poate fi referit fie la clasa în sine, fie la instanțe ale clasei. O metodă aparținând unei clase și asociată clasei (metoda statică) poate fi apelată de la sine și are acces la variabilele statice ale clasei. O metodă asociată cu o instanță de clasă (metoda obișnuită) poate fi apelată numai pe obiectul însuși și are acces atât la câmpurile statice ale clasei, cât și la câmpurile obișnuite ale unui anumit obiect (când este apelată, acest obiect va fi transmis ca un parametru de metodă ascuns). De exemplu, numărul total de șiruri create poate fi găsit de oriunde în program, dar lungimea unui anumit șir poate fi găsită doar specificând, într-un fel sau altul, lungimea căruia șir vom măsura.

Interfață și implementare, implementare moștenire

În programare, există conceptul de interfață de programare, ceea ce înseamnă o listă de posibile calcule pe care una sau alta parte a programului le poate efectua. Aceasta include o descriere: ce argumente și în ce ordine trebuie să fie transmise la intrarea algoritmilor din listă, precum și ce și în ce formă vor returna. Interfața tipului de date abstract a fost inventată pentru descrierea oficială a unei astfel de liste. Algoritmii înșiși, adică codul programului real care va efectua toate aceste calcule, nu sunt specificați de interfață, sunt programați separat și se numesc implementarea interfeței .

Interfețele de programare, precum și clasele, pot fi extinse prin moștenire , care este unul dintre mijloacele importante de reutilizare a codului în OOP. O clasă sau interfață moștenită va conține tot ceea ce este specificat pentru toate clasele sale părinte (în funcție de limbajul de programare și de platformă, poate exista de la zero la infinit). De exemplu, puteți crea propria versiune a unui șir de text prin moștenirea clasei „șirul meu de text” din clasa „șir de text” deja existentă, în timp ce se presupune că programatorul nu va trebui să rescrie algoritmii de căutare și așa mai departe, deoarece acestea vor fi moștenite automat din clasa terminată, iar orice instanță a clasei „linia mea de text” poate fi transmisă nu numai metodelor gata făcute ale clasei părinte „linia de text” pentru a efectua calculele necesare, ci în general oricărui algoritm care poate lucra cu obiecte de tip „linie de text”, deoarece instanțele ambelor clase sunt compatibile cu interfața.

Clasa vă permite nu numai să setați interfața de programare pentru sine și pentru instanțele sale, ci și să scrieți în mod explicit codul responsabil pentru calcule. Dacă, la crearea noului nostru tip de date, moștenim interfața, atunci vom putea transmite o instanță a tipului nostru de date oricărui algoritm care poate funcționa cu această interfață. Totuși, va trebui să scriem noi înșine implementarea interfeței, adică acei algoritmi pe care algoritmul de interes pentru noi îi va folosi pentru a efectua calcule folosind instanța noastră. În același timp, prin moștenirea unei clase, moștenim automat codul gata făcut pentru interfață (nu este întotdeauna cazul, clasa părinte poate necesita implementarea unor algoritmi în clasa fii fără greș). Această capacitate de a moșteni din cod este ceea ce face clar că într-un program orientat pe obiecte, tipul de date al unei clase definește atât o interfață, cât și o implementare pentru toate instanțele sale.

Starea obiectului, conceptul de domenii, constructori

Una dintre problemele programării structurate cu care se luptă OOP este problema menținerii valorii corecte a variabilelor programului. Adesea, diferite variabile ale programului stochează valori legate logic, iar programatorul este responsabil pentru menținerea acestei conectivitati logice, adică conectivitatea nu este menținută automat. Un exemplu sunt steagurile „trase” și „așteptând un bonus la sfârșitul anului”, când, conform regulilor departamentului de personal, o persoană poate fi simultan să nu fie concediată și să nu aștepte un bonus, să nu fie concediată și să aștepte un bonus, concediat și care nu așteaptă un bonus, dar nu poate fi concediat și așteaptă un bonus. Adică, orice parte a programului care bifează caseta „demisă” ar trebui să debifeze întotdeauna caseta „Așteptăm bonusuri de sfârșit de an”.

O modalitate bună de a rezolva această problemă este să faceți neschimbat indicatorul „declanșat” pentru toate părțile programului, cu excepția uneia specificate în mod specific. În această secțiune specifică, totul va fi scris o dată și corect, iar toți ceilalți vor trebui să se refere la această secțiune ori de câte ori vor să bifeze sau să debifeze caseta „declanșată”.

Într-un program orientat pe obiecte, indicatorul „declanșat” va fi declarat membru privat al unei clase, iar metodele publice corespunzătoare vor fi scrise pentru a-l citi și schimba. Regulile care determină posibilitatea sau imposibilitatea modificării directe a oricăror variabile se numesc reguli de stabilire a domeniilor de acces. Cuvintele „privat” și „public” în acest caz sunt așa-numiții „ modificatori de acces ”. Se numesc modificatori deoarece în unele limbi sunt folosiți pentru a modifica permisiunile setate anterior atunci când o clasă este moștenită. Împreună, clasele și modificatorii de acces definesc o zonă de acces, adică fiecare secțiune de cod, în funcție de clasa căreia îi aparține, va avea propria zonă de acces în ceea ce privește anumite elemente (membri) din clasa sa și alte clase, inclusiv variabile. , metode, funcții, constante etc. Există o regulă de bază: nimic dintr-o clasă nu poate vedea membrii privați ai altei clase. În raport cu alte reguli mai complexe, diferitele limbi au modificatori de acces și reguli diferiți pentru modul în care interacționează cu clasele.

Aproape fiecărui membru al clasei i se poate seta un modificator de acces (cu excepția constructorilor statici și a altor câteva lucruri). Majoritatea limbajelor de programare orientate pe obiecte acceptă următorii modificatori de acces:

Problema menținerii stării corecte a variabilelor este de asemenea relevantă chiar din primul moment al stabilirii valorilor inițiale. Pentru a face acest lucru, clasele oferă metode/funcții speciale numite constructori. Niciun obiect (instanța unei clase) nu poate fi creat altfel decât apelând codul constructorului pentru execuție, care va returna apelantului o instanță creată și populată corect a clasei. În multe limbaje de programare, tipul de date „struct”, precum o clasă, poate conține variabile și metode, dar instanțe de structuri, rămânând doar o zonă marcată a RAM, pot fi create ocolind constructorii, ceea ce este interzis pentru instanțe de clasă ( cu excepția metodelor excepționale speciale pentru ocolirea tuturor regulilor OOP similare furnizate în unele limbi și platforme). Aceasta arată diferența dintre clase și alte tipuri de date - este necesar un apel de constructor.

Abordare practică

În limbajele moderne de programare orientate pe obiecte (inclusiv php , Java , C++ , Oberon , Python , Ruby , Smalltalk , Object Pascal ) crearea unei clase se reduce la scrierea unei structuri care să conțină un set de câmpuri și metode (printre acestea din urmă, constructori). joacă un rol deosebit, destructori, finalizatori). În practică, o clasă poate fi înțeleasă ca un șablon în funcție de care sunt create obiecte - instanțe ale acestei clase. Toate instanțele aceleiași clase sunt create conform aceluiași șablon, deci au același set de câmpuri și metode.

Relațiile dintre clase

Tipuri de clase

Domeniul de aplicare

Domeniul de aplicare al membrilor clasei (adică domeniul de aplicare al codului din care pot fi accesați printr-un nume necalificat - fără a specifica numele clasei sau obiectului) nu depinde de domeniul lor și este întotdeauna același cu codul de metode de clasă.

Sfera de aplicare a clasei în sine este definită diferit în diferite limbaje de programare. În unele limbi (cum ar fi Delphi ) toate clasele au vizibilitate globală (ținând cont de vizibilitatea modulului ), în altele (cum ar fi Java ) domeniul de aplicare al unei clase este asociat cu unitatea de compilare care o conține (în Java). - cu un pachet ), în altele (cum ar fi C ++ și C# ), domeniul de aplicare al unei clase este determinat de spații de nume ( namespaces ), care sunt stabilite în mod explicit de programator și pot sau nu se potrivesc cu unitățile de compilare.

Clase în Object Pascal (mediu Delphi)

În Delphi , clasa este descrisă după cum urmează:

TMyClass = class ( TObject ) private {Elementele descrise în această secțiune nu sunt accesibile din exterior (în afara clasei, dar disponibile în cadrul modulului).} {Câmpurile de clasă se găsesc de obicei aici.} strict private {Pentru Delphi 2007 și versiuni ulterioare. Elementele descrise în această secțiune sunt disponibile numai în cadrul clasei} protejat {Elementele descrise în această secțiune sunt disponibile numai pentru clasă și toți descendenții acesteia.} public {Elementele descrise în această secțiune sunt disponibile pentru toată lumea.} publicat {Elementele descrise în această secțiune sunt disponibile pentru toată lumea și sunt afișate în Object Inspector'e.} end ;
  • TMyClass - numele clasei;
  • class - un cuvânt cheie care începe o definiție de clasă (în versiunile mai vechi exista și un cuvânt cheie object);
  • TObject - clasa strămoșilor, dacă există moștenire ;
  • private, protected, public, published - cuvinte cheie care definesc accesul ierarhic la câmpuri și metode sub forma desemnării secțiunilor zonelor de acces .

O instanță (obiect) a clasei este creată astfel:

MyClass := TMyClass . a crea ;

Distrus astfel:

FreeAndNil ( MyClass ) ; SAU MyClass . Gratuit ;

Clase în C++

O clasă în C++ este creată astfel:

class MyClass : public ParentClass // ParentClass - clasa strămoșilor, dacă există { public : // elementele din această secțiune sunt accesibile din orice parte a programului MyClass (); // constructor ~ MyClass (); // destructor protejat : // elementele din această secțiune sunt accesibile din clasă și descendenții ei private : // elementele din această secțiune sunt accesibile numai din clasă; acesta este domeniul implicit };

Odată creată, o clasă este considerată un tip de date cu drepturi depline și, prin urmare, instanțe ale clasei sunt create după cum urmează:

MyClass myinstance ;

Apelarea membrilor clasei:

instanța mea . membru al clasei

O instanță a clasei este distrusă, ca orice variabilă, numai dacă funcția în care a fost creată și-a încheiat activitatea sau dacă memoria dinamică alocată pentru clasă a fost eliberată forțat .

Clasele în C#

Clasele în C# sunt definite după cum urmează:

public class MyClass { //Membru disponibil oricărei clase din program public int k ; //Membru disponibil oricărei clase din același program modul intern int l ; //Membru disponibil oricărei clase din același modul de program, sau numai pentru clasa curentă și toate subclasele sale dintr-un alt modul protejat intern int m ; //Membru accesibil doar pentru clasa curentă și pentru toate subclasele sale protejate int n ; //Membru accesibil numai din clasa curentă (implicit). private int fg ; }

Spre deosebire de C++, modificatorii de acces trebuie să fie specificați pe bază de membru. Clasele anonime pot fi definite într-o metodă astfel:

public void A face ceva () { var person = new { Name = "Marguerite" ; Varsta = 15 ; } var pet = new { Nume = "Dunya" ; Tip = "Testoasa" ; Proprietar = persoana ; } Consola . WriteLine ( "Vârsta proprietarului animalului de companie: " + animal de companie . Proprietar . Vârsta ); }

Cursuri în Ruby

Clasele în limbajul Ruby sunt definite după cum urmează:

class MyClass def initialize # Constructor (opțional) end public # Identificatorul public este opțional deoarece setat implicit, # indică faptul că metodele care urmează sunt disponibile de oriunde în program def public_method # Public method end protected # Identificatorul protejat indică faptul că următoarele metode # vor fi disponibile numai pentru membrii acestei clase și ai claselor copil def protected_method # Protected method end private # Identificatorul privat indică faptul că următoarele metode # vor fi disponibile numai pentru membrii acestei clase def private_method # Private method end end

Crearea unei instanțe a unei clase:

obiect = MyClass . nou

Distrugerea unei instanțe a unei clase nu este necesară: se întâmplă automat folosind „colectorul de gunoi” de îndată ce ultima referință la aceasta dispare din memorie.

Clasuri în Python

Definirea unei clase în Python folosind operatorul class:

clasa MyClass : def __init__ ( self , arg ): """Constructor""" self . _arg = arg # parametru obiect def method1 ( self , x ): """metoda inclusă în interfața clasei""" def _method2 ( self , x ): """o metodă care nu face parte dintr-o interfață de clasă""" def __method2 ( self , x ): """metoda este disponibilă numai în cadrul clasei""" @staticmethod def method3 ( arg1 , arg2 , ... ): """o metodă statică care poate fi apelată atât din instanțe ale clasei, cât și din clasa însăși""" @classmethod def method4 ( cls , arg1 , arg2 , ... ): """metoda clasei, apelabilă atât din instanțe ale clasei, cât și din clasa în sine, cu acces la metode și parametri interni"""

Crearea unei instanțe a unei clase:

myinstance = MyClass ( 4 )

Distrugerea explicită a instanței clasei nu este necesară, deoarece Python are un „colector de gunoi” automat. Cu toate acestea, puteți elimina în mod explicit o referință la un obiect (o instanță a unei clase sau clasa în sine) astfel:

del myinstance

Clase în JavaScript

Definirea unei clase în JavaScript folosind operatorul class:

class MyClass { constructor ( arg1 , arg2 , ...) { //constructor (opțional) this . arg1 = arg1 ; aceasta . arg2 = arg2 ; } method1 () { // Metoda obișnuită } metoda statica { // metoda statica } }

Crearea unei instanțe a unei clase:

var myinstance = new MyClass ( 4 , 2 )

Distrugerea unei instanțe de clasă nu este necesară: se întâmplă automat folosind „colectorul de gunoi” de îndată ce ultima referință la aceasta dispare din memorie.

Clasele în limbajul Java

Fiecare clasă în Java este de obicei creată într-un fișier separat, numele fișierului trebuie să se potrivească cu numele clasei. În acest caz, va fi MyClass.java

Definirea unei clase Java folosind operatorul class:


class MyClass { String name = "Exemplu" ; // "Constructor" public MyClass ( String name ) { this . nume = nume ; } // "Metoda" public String getName () { return name ; } }

Crearea unei instanțe a unei clase:

MyClass my = new MyClass ( "Exemplu 2" );

O instanță a unei clase este distrusă automat de către „colectorul de gunoi”.

Link -uri