fbpx
Wikipedia

Class invariant

In computer programming, specifically object-oriented programming, a class invariant (or type invariant) is an invariant used for constraining objects of a class. Methods of the class should preserve the invariant. The class invariant constrains the state stored in the object.

Class invariants are established during construction and constantly maintained between calls to public methods. Code within functions may break invariants as long as the invariants are restored before a public function ends. With concurrency, maintaining the invariant in methods typically requires a critical section to be established by locking the state using a mutex.

An object invariant, or representation invariant, is a computer programming construct consisting of a set of invariant properties that remain uncompromised regardless of the state of the object. This ensures that the object will always meet predefined conditions, and that methods may, therefore, always reference the object without the risk of making inaccurate presumptions. Defining class invariants can help programmers and testers to catch more bugs during software testing.

Class invariants and inheritance

The useful effect of class invariants in object-oriented software is enhanced in the presence of inheritance. Class invariants are inherited, that is, "the invariants of all the parents of a class apply to the class itself."[1]

Inheritance can allow descendant classes to alter implementation data of parent classes, so it would be possible for a descendant class to change the state of instances in a way that made them invalid from the viewpoint of the parent class. The concern for this type of misbehaving descendant is one reason object-oriented software designers give for favoring composition over inheritance (i.e., inheritance breaks encapsulation).[2]

However, because class invariants are inherited, the class invariant for any particular class consists of any invariant assertions coded immediately on that class in conjunction with all the invariant clauses inherited from the class's parents. This means that even though descendant classes may have access to the implementation data of their parents, the class invariant can prevent them from manipulating those data in any way that produces an invalid instance at runtime.

Programming language support

Assertions

Common programming languages like Python,[3] PHP,[4] JavaScript,[citation needed] C++ and Java support assertions by default, which can be used to define class invariants. A common pattern to implement invariants in classes is for the constructor of the class to throw an exception if the invariant is not satisfied. Since methods preserve the invariants, they can assume the validity of the invariant and need not explicitly check for it.

Native support

The class invariant is an essential component of design by contract. So, programming languages that provide full native support for design by contract, such as Eiffel, Ada, and D, will also provide full support for class invariants.

Non-native support

For C++, the Loki Library provides a framework for checking class invariants, static data invariants, and exception safety.

For Java, there is a more powerful tool called Java Modeling Language that provides a more robust way of defining class invariants.

Examples

Native support

Ada

The Ada programming language has native support for type invariants (as well as pre- and postconditions, subtype predicates, etc.). A type invariant may be given on a private type (for example to define a relationship between its abstract properties), or on its full definition (typically to help in verifying the correctness of the implementation of the type).[5] Here is an example of a type invariant given on the full definition of a private type used to represent a logical stack. The implementation uses an array, and the type invariant specifies certain properties of the implementation that enable proofs of safety. In this case, the invariant ensures that, for a stack of logical depth N, the first N elements of the array are valid values. The Default_Initial_Condition of the Stack type, by specifying an empty stack, ensures the initial truth of the invariant, and Push preserves the invariant. The truth of the invariant then enables Pop to rely on the fact that the top of the stack is a valid value, which is needed to prove Pop's postcondition. A more complex type invariant would enable the proof of full functional correctness, such as that Pop returns the value passed into a corresponding Push, but in this case we are merely trying to prove that Pop does not return an Invalid_Value.

generic type Item is private; Invalid_Value : in Item; package Stacks is type Stack(Max_Depth : Positive) is private with Default_Initial_Condition => Is_Empty (Stack); function Is_Empty(S : in Stack) return Boolean; function Is_Full(S : in Stack) return Boolean; procedure Push(S : in out Stack; I : in Item) with Pre => not Is_Full(S) and then I /= Invalid_Value, Post => not Is_Empty(S); procedure Pop(S : in out Stack; I : out Item) with Pre => not Is_Empty(S), Post => not Is_Full(S) and then I /= Invalid_Value; private type Item_Array is array (Positive range <>) of Item; type Stack(Max_Depth : Positive) is record Length : Natural := 0; Data : Item_Array (1 .. Max_Depth) := (others => Invalid_Value); end record with Type_Invariant => Length <= Max_Depth and then (for all J in 1 .. Length => Data (J) /= Invalid_Value); function Is_Empty(S : in Stack) return Boolean is (S.Length = 0); function Is_Full(S : in Stack) return Boolean is (S.Length = S.Max_Depth); end Stacks; 

D

D programming language has native support of class invariants, as well as other contract programming techniques. Here is an example from the official documentation.[6]

class Date {  int day;  int hour;  invariant() {  assert(day >= 1 && day <= 31);  assert(hour >= 0 && hour <= 23);  } } 

Eiffel

In Eiffel, the class invariant appears at the end of the class following the keyword invariant.

class  DATE create  make feature {NONE} -- Initialization  make (a_day: INTEGER; a_hour: INTEGER)  -- Initialize `Current' with `a_day' and `a_hour'.  require  valid_day: a_day >= 1 and a_day <= 31  valid_hour: a_hour >= 0 and a_hour <= 23  do  day := a_day  hour := a_hour  ensure  day_set: day = a_day  hour_set: hour = a_hour  end feature -- Access  day: INTEGER  -- Day of month for `Current'  hour: INTEGER  -- Hour of day for `Current' feature -- Element change  set_day (a_day: INTEGER)  -- Set `day' to `a_day'  require  valid_argument: a_day >= 1 and a_day <= 31  do  day := a_day  ensure  day_set: day = a_day  end  set_hour (a_hour: INTEGER)  -- Set `hour' to `a_hour'  require  valid_argument: a_hour >= 0 and a_hour <= 23  do  hour := a_hour  ensure  hour_set: hour = a_hour  end invariant  valid_day: day >= 1 and day <= 31  valid_hour: hour >= 0 and hour <= 23 end 

Non-native support

C++

The Loki (C++) library provides a framework written by Richard Sposato for checking class invariants, static data invariants, and exception safety level.

This is an example of how class can use Loki::Checker to verify invariants remain true after an object changes. The example uses a geopoint object to store a location on Earth as a coordinate of latitude and longitude.

The geopoint invariants are:

  • latitude may not be more than 90° north.
  • latitude may not be less than -90° south.
  • longitude may not be more than 180° east.
  • longitude may not be less than -180° west.
#include <loki/Checker.h> // Needed to check class invariants. #include <Degrees.hpp> class GeoPoint {  public:  GeoPoint(Degrees latitude, Degrees longitude);  /// Move function will move location of GeoPoint.  void Move(Degrees latitude_change, Degrees longitude_change) {  // The checker object calls IsValid at function entry and exit to prove this  // GeoPoint object is valid. The checker also guarantees GeoPoint::Move  // function will never throw.  CheckFor::CheckForNoThrow checker(this, &IsValid);  latitude_ += latitude_change;  if (latitude_ >= 90.0) latitude_ = 90.0;  if (latitude_ <= -90.0) latitude_ = -90.0;  longitude_ += longitude_change;  while (longitude_ >= 180.0) longitude_ -= 360.0;  while (longitude_ <= -180.0) longitude_ += 360.0;  }  private:  /** @note CheckFor performs validity checking in many functions to determine  if the code violated any invariants, if any content changed, or if the  function threw an exception.  */  using CheckFor = ::Loki::CheckFor<const GeoPoint>;  /// This function checks all object invariants.  bool IsValid() const {  assert(this != nullptr);  assert(latitude_ >= -90.0);  assert(latitude_ <= 90.0);  assert(longitude_ >= -180.0);  assert(longitude_ <= 180.0);  return true;  }  Degrees latitude_; ///< Degrees from equator. Positive is north, negative is  ///< south.  Degrees longitude_; ///< Degrees from Prime Meridian. Positive is east,  ///< negative is west. } 

Java

This is an example of a class invariant in the Java programming language with Java Modeling Language. The invariant must hold to be true after the constructor is finished and at the entry and exit of all public member functions. Public member functions should define precondition and postcondition to help ensure the class invariant.

public class Date { int /*@spec_public@*/ day; int /*@spec_public@*/ hour; /*@invariant day >= 1 && day <= 31; @*/ //class invariant /*@invariant hour >= 0 && hour <= 23; @*/ //class invariant /*@  @requires d >= 1 && d <= 31;  @requires h >= 0 && h <= 23;  @*/ public Date(int d, int h) { // constructor day = d; hour = h; } /*@  @requires d >= 1 && d <= 31;  @ensures day == d;  @*/ public void setDay(int d) { day = d; } /*@  @requires h >= 0 && h <= 23;  @ensures hour == h;  @*/ public void setHour(int h) { hour = h; } } 

References

  1. ^ Meyer, Bertrand. Object-Oriented Software Construction, second edition, Prentice Hall, 1997, p. 570.
  2. ^ E. Gamma, R. Helm, R. Johnson, and J. Vlissides. Design Patterns: Elements of Reusable Object-Oriented Software. Addison-Wesley, Reading, Massachusetts, 1995., p. 20.
  3. ^ Official Python Docs, assert statement
  4. ^ "PHP assert function". from the original on 2001-03-21.
  5. ^ "Ada Reference Manual 7.3.2 Type Invariants". ada-auth.org. Retrieved 2022-11-27.
  6. ^ "Contract Programming - D Programming Language". dlang.org. Retrieved 2020-10-29.

class, invariant, this, article, about, computer, programming, concept, mathematical, concept, equivalence, class, invariant, mathematics, this, article, needs, additional, citations, verification, please, help, improve, this, article, adding, citations, relia. This article is about the computer programming concept For the mathematical concept see Equivalence class and Invariant mathematics This article needs additional citations for verification Please help improve this article by adding citations to reliable sources Unsourced material may be challenged and removed Find sources Class invariant news newspapers books scholar JSTOR August 2010 Learn how and when to remove this template message In computer programming specifically object oriented programming a class invariant or type invariant is an invariant used for constraining objects of a class Methods of the class should preserve the invariant The class invariant constrains the state stored in the object Class invariants are established during construction and constantly maintained between calls to public methods Code within functions may break invariants as long as the invariants are restored before a public function ends With concurrency maintaining the invariant in methods typically requires a critical section to be established by locking the state using a mutex An object invariant or representation invariant is a computer programming construct consisting of a set of invariant properties that remain uncompromised regardless of the state of the object This ensures that the object will always meet predefined conditions and that methods may therefore always reference the object without the risk of making inaccurate presumptions Defining class invariants can help programmers and testers to catch more bugs during software testing Contents 1 Class invariants and inheritance 2 Programming language support 2 1 Assertions 2 2 Native support 2 3 Non native support 3 Examples 3 1 Native support 3 1 1 Ada 3 1 2 D 3 1 3 Eiffel 3 2 Non native support 3 2 1 C 3 2 2 Java 4 ReferencesClass invariants and inheritance EditThe useful effect of class invariants in object oriented software is enhanced in the presence of inheritance Class invariants are inherited that is the invariants of all the parents of a class apply to the class itself 1 Inheritance can allow descendant classes to alter implementation data of parent classes so it would be possible for a descendant class to change the state of instances in a way that made them invalid from the viewpoint of the parent class The concern for this type of misbehaving descendant is one reason object oriented software designers give for favoring composition over inheritance i e inheritance breaks encapsulation 2 However because class invariants are inherited the class invariant for any particular class consists of any invariant assertions coded immediately on that class in conjunction with all the invariant clauses inherited from the class s parents This means that even though descendant classes may have access to the implementation data of their parents the class invariant can prevent them from manipulating those data in any way that produces an invalid instance at runtime Programming language support EditAssertions Edit Common programming languages like Python 3 PHP 4 JavaScript citation needed C and Java support assertions by default which can be used to define class invariants A common pattern to implement invariants in classes is for the constructor of the class to throw an exception if the invariant is not satisfied Since methods preserve the invariants they can assume the validity of the invariant and need not explicitly check for it Native support Edit The class invariant is an essential component of design by contract So programming languages that provide full native support for design by contract such as Eiffel Ada and D will also provide full support for class invariants Non native support Edit For C the Loki Library provides a framework for checking class invariants static data invariants and exception safety For Java there is a more powerful tool called Java Modeling Language that provides a more robust way of defining class invariants Examples EditNative support Edit Ada Edit The Ada programming language has native support for type invariants as well as pre and postconditions subtype predicates etc A type invariant may be given on a private type for example to define a relationship between its abstract properties or on its full definition typically to help in verifying the correctness of the implementation of the type 5 Here is an example of a type invariant given on the full definition of a private type used to represent a logical stack The implementation uses an array and the type invariant specifies certain properties of the implementation that enable proofs of safety In this case the invariant ensures that for a stack of logical depth N the first N elements of the array are valid values The Default Initial Condition of the Stack type by specifying an empty stack ensures the initial truth of the invariant and Push preserves the invariant The truth of the invariant then enables Pop to rely on the fact that the top of the stack is a valid value which is needed to prove Pop s postcondition A more complex type invariant would enable the proof of full functional correctness such as that Pop returns the value passed into a corresponding Push but in this case we are merely trying to prove that Pop does not return an Invalid Value generic type Item is private Invalid Value in Item package Stacks is type Stack Max Depth Positive is private with Default Initial Condition gt Is Empty Stack function Is Empty S in Stack return Boolean function Is Full S in Stack return Boolean procedure Push S in out Stack I in Item with Pre gt not Is Full S and then I Invalid Value Post gt not Is Empty S procedure Pop S in out Stack I out Item with Pre gt not Is Empty S Post gt not Is Full S and then I Invalid Value private type Item Array is array Positive range lt gt of Item type Stack Max Depth Positive is record Length Natural 0 Data Item Array 1 Max Depth others gt Invalid Value end record with Type Invariant gt Length lt Max Depth and then for all J in 1 Length gt Data J Invalid Value function Is Empty S in Stack return Boolean is S Length 0 function Is Full S in Stack return Boolean is S Length S Max Depth end Stacks D Edit D programming language has native support of class invariants as well as other contract programming techniques Here is an example from the official documentation 6 class Date int day int hour invariant assert day gt 1 amp amp day lt 31 assert hour gt 0 amp amp hour lt 23 Eiffel Edit In Eiffel the class invariant appears at the end of the class following the keyword invariant class DATE create make feature NONE Initialization make a day INTEGER a hour INTEGER Initialize Current with a day and a hour require valid day a day gt 1 and a day lt 31 valid hour a hour gt 0 and a hour lt 23 do day a day hour a hour ensure day set day a day hour set hour a hour end feature Access day INTEGER Day of month for Current hour INTEGER Hour of day for Current feature Element change set day a day INTEGER Set day to a day require valid argument a day gt 1 and a day lt 31 do day a day ensure day set day a day end set hour a hour INTEGER Set hour to a hour require valid argument a hour gt 0 and a hour lt 23 do hour a hour ensure hour set hour a hour end invariant valid day day gt 1 and day lt 31 valid hour hour gt 0 and hour lt 23 end Non native support Edit C Edit The Loki C library provides a framework written by Richard Sposato for checking class invariants static data invariants and exception safety level This is an example of how class can use Loki Checker to verify invariants remain true after an object changes The example uses a geopoint object to store a location on Earth as a coordinate of latitude and longitude The geopoint invariants are latitude may not be more than 90 north latitude may not be less than 90 south longitude may not be more than 180 east longitude may not be less than 180 west include lt loki Checker h gt Needed to check class invariants include lt Degrees hpp gt class GeoPoint public GeoPoint Degrees latitude Degrees longitude Move function will move location of GeoPoint void Move Degrees latitude change Degrees longitude change The checker object calls IsValid at function entry and exit to prove this GeoPoint object is valid The checker also guarantees GeoPoint Move function will never throw CheckFor CheckForNoThrow checker this amp IsValid latitude latitude change if latitude gt 90 0 latitude 90 0 if latitude lt 90 0 latitude 90 0 longitude longitude change while longitude gt 180 0 longitude 360 0 while longitude lt 180 0 longitude 360 0 private note CheckFor performs validity checking in many functions to determine if the code violated any invariants if any content changed or if the function threw an exception using CheckFor Loki CheckFor lt const GeoPoint gt This function checks all object invariants bool IsValid const assert this nullptr assert latitude gt 90 0 assert latitude lt 90 0 assert longitude gt 180 0 assert longitude lt 180 0 return true Degrees latitude lt Degrees from equator Positive is north negative is lt south Degrees longitude lt Degrees from Prime Meridian Positive is east lt negative is west Java Edit This is an example of a class invariant in the Java programming language with Java Modeling Language The invariant must hold to be true after the constructor is finished and at the entry and exit of all public member functions Public member functions should define precondition and postcondition to help ensure the class invariant public class Date int spec public day int spec public hour invariant day gt 1 amp amp day lt 31 class invariant invariant hour gt 0 amp amp hour lt 23 class invariant requires d gt 1 amp amp d lt 31 requires h gt 0 amp amp h lt 23 public Date int d int h constructor day d hour h requires d gt 1 amp amp d lt 31 ensures day d public void setDay int d day d requires h gt 0 amp amp h lt 23 ensures hour h public void setHour int h hour h References Edit Meyer Bertrand Object Oriented Software Construction second edition Prentice Hall 1997 p 570 E Gamma R Helm R Johnson and J Vlissides Design Patterns Elements of Reusable Object Oriented Software Addison Wesley Reading Massachusetts 1995 p 20 Official Python Docs assert statement PHP assert function Archived from the original on 2001 03 21 Ada Reference Manual 7 3 2 Type Invariants ada auth org Retrieved 2022 11 27 Contract Programming D Programming Language dlang org Retrieved 2020 10 29 Retrieved from https en wikipedia org w index php title Class invariant amp oldid 1125369112, wikipedia, wiki, book, books, library,

article

, read, download, free, free download, mp3, video, mp4, 3gp, jpg, jpeg, gif, png, picture, music, song, movie, book, game, games.