Încapsulare (programare)

Versiunea actuală a paginii nu a fost încă revizuită de colaboratori experimentați și poate diferi semnificativ de versiunea revizuită pe 21 septembrie 2016; controalele necesită 79 de modificări .

Encapsulation ( eng.  encapsulation , din lat.  in capsula ) - în informatică , procesul de separare a elementelor abstracțiilor care îi determină structura (date) și comportamentul (metode); încapsularea are scopul de a izola obligațiile contractuale ale unei abstracții (protocol/interfață) de implementarea acestora. În practică, aceasta înseamnă că o clasă ar trebui să fie formată din două părți: o interfață și o implementare. Implementarea majorității limbajelor de programare ( C++ , C# , Java și altele) oferă un mecanism de ascundere care vă permite să diferențiați accesul la diferite părți ale componentei.

Încapsularea este adesea privită ca un concept exclusiv al programării orientate pe obiecte (OOP) , dar de fapt se găsește pe scară largă în altele (vezi subtiparea înregistrărilor și polimorfismul înregistrărilor și variantelor ). În OOP, încapsularea este strâns legată de principiul abstracției datelor (a nu se confunda cu tipurile de date abstracte, ale căror implementări oferă încapsulare, dar sunt de natură diferită). Acest lucru, în special, implică diferențe de terminologie în diferite surse. În comunitatea C++ sau Java , încapsularea fără ascundere este în general considerată inferioară. Cu toate acestea, unele limbi (de exemplu , Smalltalk , Python ) implementează încapsularea, dar nu prevăd deloc ascunderea. Alții ( Standard , OCaml ) separă rigid aceste concepte ca fiind ortogonale și le oferă într-un mod semantic diferit (vezi ascunderea în limbajul modulului ML ).

Detalii

În general, în diferite limbaje de programare, termenul „încapsulare” se referă la una sau ambele dintre următoarele notații în același timp:

Cuvântul „încapsulare” provine din latinescul in capsula  – „așezare în coajă”. Astfel, încapsularea poate fi înțeleasă intuitiv ca izolare, închiderea a ceva străin pentru a exclude influența asupra mediului, asigurarea disponibilității conținutului principal, evidențierea conținutului principal prin plasarea a tot ceea ce interferează, secundar într-o capsulă condiționată ( cutie neagră ).

Exemple

Ada

pachetul Stacks este tipul Stack_Type este privat ; procedura Push ( Stiva : in out Stack_Type ; Val : Integer ); privat tipul Stack_Data este o matrice ( 1 .. 100 ) de Integer ; tipul Stack_Type este înregistrare Max : Integer := 0,3 ; Date : Stack_Data ; sfârșitul înregistrării ; sfârşitul stivelor ;

C++

clasa A { public : int a , b ; // date interfețe publice int Return_Something (); // metoda interfeței publice private : int Aa , Ab ; //date ascunse void Do_Something (); //metoda ascunsă };

Clasa A încapsulează proprietățile Aa, Ab și metoda Do_Something(), reprezentând interfața externă Return_Something, a, b.

C#

Scopul încapsulării este de a se asigura că starea internă a unui obiect este consecventă. În C#, proprietățile publice și metodele unui obiect sunt utilizate pentru încapsulare. Variabilele, cu rare excepții, nu ar trebui să fie disponibile public. Încapsularea poate fi ilustrată cu un exemplu simplu. Să presupunem că trebuie să stocăm o valoare reală și reprezentarea ei șir (de exemplu, pentru a nu converti de fiecare dată în cazul utilizării frecvente). Un exemplu de implementare fără încapsulare este următorul:

class NoEncapsulation { public double ValueDouble ; șir public ValueString ; }

În același timp, putem modifica separat atât Valoarea în sine, cât și reprezentarea șirului acesteia, iar la un moment dat acestea se pot nepotrivi (de exemplu, ca urmare a unei excepții). Exemplu de implementare folosind încapsulare:

class EncapsulationExample { private double valueDouble ; șir privat valueString ; public double ValueDouble { get { return valueDouble ; } set { valueDouble = valoare ; valueString = valoare . ToString (); } } public string ValueString { get { return valueString ; } set { double tmp_value = Convert . ToDouble ( valoare ); //o excepție poate apărea aici valueDouble = tmp_value ; valueString = valoare ; } } }

Aici, variabilele valueDouble și valueString pot fi accesate numai prin proprietățile ValueDouble și ValueString . Dacă încercăm să atribuim un șir invalid proprietății ValueString și apare o excepție în momentul conversiei, atunci variabilele interne vor rămâne în aceeași stare, consecventă, deoarece excepția determină închiderea procedurii.

Delphi

În Delphi, pentru a crea câmpuri sau metode ascunse , este suficient să le declarați în fișierul private.

TMyClass = clasă privată FMyField : Integer ; procedura SetMyField ( const Value : Integer ) ; funcția GetMyField : Integer ; proprietate publică MyField : Integer read GetMyField scrie SetMyField ; sfârşitul ;

Pentru a crea o interfață pentru accesarea câmpurilor ascunse, Delphi a introdus proprietăți .

PHP

class A { private string $a ; // proprietate ascunsă private int $b ; // proprietate ascunsă funcția privată doSomething () : void //metoda ascunsă { //acțiuni } funcția publică returna ceva () : int //metoda publică { //acțiuni } }

În acest exemplu, clasa A are proprietățile $a și $b închise pentru a preveni deteriorarea acestor proprietăți de către alt cod care trebuie să aibă permisiuni numai pentru citire.

Java

clasa întâi { private int a ; private int b ; private void doSomething () { //metoda ascunsă //acțiuni } public int getSomething () { //metoda publică returnează un ; } }

JavaScript

fie A = funcția () { // privat lasă _proprietate ; let _privateMethod = function () { /* actiuni */ } // metoda privata // public aceasta . getProperty = function () { // interfata publica returnează _proprietate ; } aceasta . setProperty = function ( value ) { // interfata publica _proprietate = valoare ; _privateMethod (); } }

sau

fie A = funcția () { // privat lasă _proprietate ; let _privateMethod = function () { /* actiuni */ } // metoda privata // public întoarce { } }

sau folosind proprietăți private

clasa A { #proprietate ; _ # privateMethod = () => { /* acțiuni */ } obține proprietatea () { // getter returneaza asta . #proprietate ; _ } set property ( value ) { // setter aceasta . # proprietate = valoare ; } }