În programare , în special programarea orientată pe obiecte , un invariant de clasă (sau invariant de tip ) este un invariant folosit pentru a constrânge obiectele unei clase. Metodele de clasă trebuie să păstreze invariantul.
În timpul creării claselor se stabilesc invarianții acestora, care sunt menținute constant între apelurile la metode publice. Încălcarea temporară a invarianței de clasă între invocările metodelor private este posibilă, deși nu este de dorit.
Un obiect invariant este un construct de programare format dintr-un set de proprietăți invariante. Acest lucru asigură că obiectul se va potrivi întotdeauna cu condițiile predefinite, astfel încât metodele se pot referi întotdeauna la obiect fără riscul de a face presupuneri imprecise. Definirea invarianților de clasă poate ajuta programatorii și testerii să găsească mai multe erori atunci când testează software-ul.
Efectul util al invarianților de clasă în programarea orientată pe obiecte este sporit de prezența moștenirii. Invarianții de clasă sunt moșteniți, adică invarianții tuturor părinților unei clase se aplică clasei în sine. [unu]
Moștenirea permite claselor descendente să modifice datele de implementare ale claselor părinte, astfel încât o clasă descendentă poate schimba starea instanțelor într-un mod care le face invalide din punctul de vedere al clasei părinte. Referirea la acest tip de copil nevalid este unul dintre motivele pentru care dezvoltatorii de software orientat pe obiecte preferă încapsularea în detrimentul moștenirii. [2]
Cu toate acestea, deoarece invarianții de clasă sunt moșteniți, invariantul de clasă pentru orice clasă anume constă din orice instrucțiuni invariante codificate direct în acea clasă, combinate cu toate clauzele invariante moștenite de la părinții acelei clase. Aceasta înseamnă că, în timp ce clasele descendente pot accesa datele de implementare ale părintelui lor, un invariant de clasă le poate împiedica să manipuleze acele date în orice mod care creează o instanță invalidă în timpul execuției.
Limbajele de programare, cum ar fi C++ și Java , acceptă aserțiuni implicite , care pot fi folosite pentru a defini invarianții de clasă. Un exemplu comun de implementare a invarianților în clase este că constructorul de clasă aruncă o excepție dacă invariantul nu este îndeplinit. Deoarece metodele păstrează invarianții, ele pot accepta validitatea unui invariant și nu trebuie să-l verifice în mod explicit.
Invariantul de clasă este o componentă esențială a programării contractelor . Astfel, limbajele de programare care oferă suport complet pentru programarea contractuală, cum ar fi Eiffel , Ada și D , vor oferi, de asemenea, suport complet pentru invarianții de clasă.
Java are un instrument mai puternic numit Java Modeling Language , care oferă o modalitate mai robustă de a defini invarianții de clasă.
Limbajul de programare D are suport încorporat pentru invarianții de clasă, precum și alte tehnici de programare prin contract. Iată un exemplu din documentația oficială.
clasa Data { int zi ; int oră ; invariant () { assert ( 1 <= zi && zi <= 31 ); afirma ( 0 <= ora && ora < 24 ); } } EiffelÎn Eiffel , un invariant de clasă este declarat la sfârșitul clasei după cuvântul cheie.
clasa DATE crea face caracteristică { NONE } -- Inițializare make ( a_day : INTEGER ; a_hour : INTEGER ) -- Inițializați „Current” cu „a_day” și „a_hour”. necesită ziua_validă : 1 <= a_day și a_day <= 31 valid_hour : 0 <= a_hour and a_hour <= 23 do day := a_day hour := a_hour asigurați day_set : day = a_day hour_set : hour = a_hour end caracteristică -- Acces day : INTEGER -- Ziua lunii pentru „Current” hour : INTEGER -- Ora zilei pentru „Current” caracteristică -- Schimbarea elementului set_day ( a_day : INTEGER ) -- Setați `day' la `a_day' require valid_argument : 1 <= a_day and a_day <= 31 do day := a_day ensure day_set : day = a_day end set_hour ( a_hour : INTEGER ) -- Setați `hour' la `a_hour' require valid_argument : 0 <= a_hour and a_hour <= 23 do hour := a_hour asigurați hour_set : hour = a_hour end invariant valid_day : 1 <= zi și zi <= 31 valid_hour : 0 <= ora și ora <= 23 endAcesta este un exemplu de invariant de clasă în limbajul de programare Java cu limbajul de modelare Java. Invariantul trebuie să fie adevărat după finalizarea constructorului și la intrarea și ieșirea tuturor membrilor funcției publice, care trebuie să definească o precondiție și o postcondiție pentru a impune invariantul de clasă.
clasă publică Data { int /*@spec_public@*/ zi ; int /*@spec_public@*/ ora ; /*@invariant 1 <= zi && zi <= 31; @*/ //invariant de clasă /*@invariant 0 <= oră && oră < 24; @*/ //invariant de clasă /*@ @ necesită 1 <= d && d <= 31; @necesită 0 <= h && h < 24; @*/ public Data ( int d , int h ) { // constructor day = d ; ora = h ; } /*@ @ necesită 1 <= d && d <= 31; @asigură ziua == d; @*/ public void setDay ( int d ) { zi = d ; } /*@ @ necesită 0 <= h && h < 24; @asigură ora == h; @*/ public void setHour ( int h ) { hour = h ; } }