Vamos agora discutir a implementação da nossa classe Sentável parte por parte.
Sentavel::Sentavel( int parAssentos, int parSuportes ) {
if( parAssentos > 0 ) {
this->set_assentos( parAssentos );
} else {
printf( "Tem que ter pelo menos um assento para ser
Sentável...\n" );
this->set_assentos( 1 );
}
if( parSuportes > 2 ) {
this->set_suportes( parSuportes );
} else {
printf( "Você é equilibrista?\nPara se equilibrar tem de ter ao
menos 3 pernas...\n" );
this->set_suportes( 3 );
}
this->set_sentantes( 0 );
}
Esse primeiro método tem uma particularidade interessante: ele possui o mesmo nome da classe! Na verdade essa convenção tem uma razão importante. Esse método é chamado de CONSTRUTOR da classe.
Quando criamos uma instância de uma classe, como veremos adiante, esse método é automaticamente chamado.
Dentro do construtor colocamos a lógica para definir nosso objeto de forma adequada, como vemos acima. Caso o programa chamador passe parâmetros inadequados para esse construtor, ele garante que o objeto criado será razoável", ou seja, terá pelo menos um assento e três pernas. O mínimo necessário para que não acabemos de traseiro no chão. Também iniciamos sem ninguém sentado. Seia complicado construir uma cadeira com alguém já sentado nela...
Sentavel::~Sentavel() {
this->set_assentos( 0 ); this->set_suportes( 0 );
}
Oooops! Esse método tem o mesmo nome do anterior?
Não. Ele é precedido pelo ~ e sempre que virmos isso em C++ reconheceremos que se trata do DESTRUTOR de uma classe.
O objetivo de um DESTRUTOR é destruir, ou seja, eliminar o objeto criado. No nosso caso, escolhemos fazer isso zerando o número de assentos e o número de suportes (pernas). Foi uma decisão de implementação, por razões didáticas. Poderíamos ter feito outras coisas, como liberar memória alocada para o objeto, por exemplo.
void Sentavel::sentar() {
if( this->get_sentantes() < this->get_assentos() ) {
this->set_sentantes( this->get_sentantes() + 1 );
printf( "Pronto, você consegui sentar!\n" );
} else {
printf( "Não tá vendo que o lugar está ocupado?\n";
}
}
Este método implementa uma ação possível para se realizada com um objeto da classe Sentável, ou seja, sentar. Perceba a lógica embutida, que é simples mas decisiva. Você só pode sentar se houver mais assentos no objeto sentável do que pessoas sentadas nele.
Para poupar espaço, pois esse artigo vai ficar grande, não vamos discutir levantar, mas sugiro que você observe a lógica de levantar na seção anterior.
Da mesma forma, vamos trazer agora dois métodos que generalizam o conceito de métodos de acesso.
void Sentavel::set_assentos( int parAssentos ) {
this->qntAssentos = parAssentos;
}
int Sentavel::get_assentos() {
return( this->qntAssentos );
}
Os métodos set_assentos e get_assentos são o que costumamos chamar de métodos de acesso. Eles servem para implementar canais únicos através dos quais as propriedades de uma classe podem ser alteradas ou obtidas.
A finalidade disso é bem simples e pode ser resumida numa frase que minha mãe costuma dizer: "Bolo que muita gente mexe acaba estragando!".
Se todo mundo puder mexer indiscriminadamente nas propriedades de um objeto, a bagunça tende a generalizar-se. Em geral isso é o que acontece com linguagens de programação que permitem o uso de variáveis globais. Quando você tem um erro envolvendo uma variável global, não tem outra alternativa a não ser verificar todo o seu código, já que ela pode ter sido alterada em qualquer ponto. Se estivermos falando de um programinha de trinta ou quarenta linhas, tudo bem... mas se estivermos falando em um sistema realmente grande, com milhares de linhas de código, uma variável global será o suficiente para enlouquecer toda uma equipe de programadores.