Assunto abordado por Cargill (1992), manter a consistencia de estados e interfaces e muito importante. Toda operacao deve deixar o objeto sobre o qual ela atua em um estado consistente. Para isso, devemos definir os invariantes dos objetos da classe e observar para que todas as construtoras e operacoes respeitem as condicoes estabelecidas.A falta de consistencia pode provocar resultados inesperados durante a execucao. Imagine o exemplo de implementacao de uma pilha com algumas construtoras. Caso o topo seja apontado para um local em uma das construtoras e para outro local em outra construtora, havera uma inconsistencia ai e o algoritmo podera funcionar de forma inesperada em alguns momentos.Veja o exemplo de implementacao da classe MyString com problemas de consistencia:class MyString { //Campos privados de MyStringprivate char[ ] s;private int length;//Funcoes auxiliares privadas de MyStringprivate void copy(char[]d, char[] a){int i;for(i=0; i<a.length && a[i]!=\0; i++){d[i] = a[i];}if (i < d.length)d[i] =\0;}private void join(char[]d,char[]a,char[]b){int i,j;for (i=0; i<a.length && a[i]!=\0; i++){d[i]= a[i];}for (j=0; j<b.length; j++)d[i+j] = b[j];d[i+j] = \0;}private int strlen(char[] a){int i = 0;while ((i < a.length) && (a[i]!=\0)) i++;return i;}//Construtoras de MyStringpublic MyString() {s = new char[80]; length = 0;}public MyString(int n) {s = new char[n]; length = n;}public MyString(char[ ] p) {length = strlen(p); s = new char[length + 1];copy(s,p);}public MyString(MyString str){length = strlen(str); this.s = new char[length];copy(this.s, str.s);}//Operacoes de Stringpublic void assign(char[ ] f) {copy(this.s, f);length = strlen(f);}public void print() {int k = strlen(this.s);for(int i=0; i< k; i++)System.out.print(s[i]);System.out.println();}//Definicao de Stringpublic void concat(MYString a, MyString b){length = strlen(a) + strlen(b);this.s = new char[length];join(this.s, a.s, b.s);}public int length( ) {return length;}}Observe que existe um problema com consistencia de estados nas duas primeiras construtoras do exemplo dado:public MyString() {s = new char[80]; length = 0;}public MyString(int n) {s = new char[n]; length = n;}O campo length recebe 0 na primeira implementacao e n na segunda. Na primeira length e o tamanho da cadeia de caractere dentro da area alocada, enquanto na segunda length e o tamanho da area alocada. Essa implementacao esta incorreta, pois, ocorreu uma inconsistencia na definicao no estado do objeto e isso pode causar conflitos durante a execucao do codigo. O correto seria que o campo length estivesse com um tamanho definido de forma igual nas duas construtoras.Uma solucao do problema seria unificar essas duas construtoras para que mantenham a consistencia no estado do campo length:public MyString(int n) throws Erro{if (n < 0) throw new Erro() ;s = new char[n]; length = 0;}public MyString( ) throws Erro {this(80);}Mesmo com a solucao apresentada para esse problema, estamos com um problema na definicao da semantica do campo length, pois, nao sabemos ao certo o que ele representa. Verifique nas partes do codigo original examinadas separadamente a seguir:// Aqui, length e o tamanho do string armazenado:public MyString(char[ ] p) {length = strlen(p); s = new char[len + 1];copy(s, p);}// Aqui, length e o tamanho da area reservada (array):public MyString(int n) throws Erro{if (n < 1) new Erro();s = new char[n]; length = n;}// Aqui, length e o tamanho do array ou do string:public MyString(MyString str){length = str.length;s = new char[length + 1];copy(s, str.s);}// Aqui, length