Até agora, nossos objetos apenas guardavam dados: uma pessoa tinha nome e idade, uma conta tinha titular e saldo. São objetos passivos, meros depósitos. Mas a promessa da orientação a objetos, lá na Aula #22, era que um objeto agrupa características e comportamentos. Chegou a hora dos comportamentos. Nesta aula, daremos aos objetos a capacidade de fazer coisas — uma conta que sabe depositar e sacar, uma pessoa que sabe se apresentar — por meio dos métodos de objeto. E, ao fazê-lo, encontraremos uma palavra especial e importante, this, que permite a um objeto referir-se a si mesmo. É quando os objetos ganham vida própria, tornando-se coisas que não só têm estado, mas agem sobre ele.
Métodos que pertencem ao objeto
Você já domina os métodos desde a Fase 3: blocos de código nomeados que executam uma tarefa. A novidade agora é que um método pode pertencer a uma classe, tornando-se um comportamento dos objetos dela. Um método definido dentro de uma classe pode acessar e modificar as características (properties e campos) do próprio objeto, encapsulando uma ação que aquele tipo de coisa sabe realizar. Veja uma classe ContaBancaria que ganha comportamentos:
class ContaBancaria
{
public string Titular { get; set; }
public decimal Saldo { get; set; }
public ContaBancaria(string titular, decimal saldoInicial)
{
Titular = titular;
Saldo = saldoInicial;
}
// MÉTODO DE OBJETO: um comportamento que a conta sabe realizar.
public void Depositar(decimal valor)
{
Saldo = Saldo + valor; // acessa e modifica a property Saldo DESTE objeto
Console.WriteLine($"Depósito de R$ {valor}. Novo saldo: R$ {Saldo}");
}
public void Sacar(decimal valor)
{
if (valor > Saldo)
{
Console.WriteLine("Saldo insuficiente.");
}
else
{
Saldo = Saldo - valor;
Console.WriteLine($"Saque de R$ {valor}. Novo saldo: R$ {Saldo}");
}
}
}
Os métodos Depositar e Sacar são comportamentos da conta. Repare que, dentro deles, acessamos Saldo diretamente — sem precisar dizer "o saldo de qual conta" — porque o método pertence ao objeto e opera sobre as características dele. Saldo = Saldo + valor significa "some valor ao saldo deste objeto". Note também que Sacar toma uma decisão (if) usando o estado do próprio objeto (o Saldo), recusando o saque se não houver fundos — o comportamento não é cego; ele respeita as regras da conta.
Chamamos os métodos de um objeto com o ponto, exatamente como acessamos suas características, e como já fazíamos com tarefas.Add ou nome.ToUpper:
ContaBancaria conta = new ContaBancaria("Ana", 1000m);
conta.Depositar(500m); // Depósito de R$ 500. Novo saldo: R$ 1500
conta.Sacar(200m); // Saque de R$ 200. Novo saldo: R$ 1300
conta.Sacar(5000m); // Saldo insuficiente.
Cada chamada aciona o comportamento daquele objeto específico, operando sobre seu saldo. Se tivéssemos duas contas, conta1.Depositar(100m) afetaria apenas o saldo de conta1, deixando conta2 intacta — porque cada método opera sobre o objeto pelo qual foi chamado. Os objetos agora fazem, não apenas guardam.
Métodos que devolvem informação sobre o objeto
Métodos de objeto também podem devolver valores (o retorno, da Fase 3), tipicamente para informar algo calculado a partir do estado do objeto. Veja uma pessoa que sabe informar se é maior de idade e que sabe se apresentar:
class Pessoa
{
public string Nome { get; set; }
public int Idade { get; set; }
public Pessoa(string nome, int idade)
{
Nome = nome;
Idade = idade;
}
// Devolve informação calculada a partir do estado do objeto:
public bool EhMaiorDeIdade()
{
return Idade >= 18;
}
// Executa uma ação usando o estado do objeto:
public void Apresentar()
{
Console.WriteLine($"Olá, meu nome é {Nome} e tenho {Idade} anos.");
}
}
Pessoa p = new Pessoa("Ana", 30);
p.Apresentar(); // Olá, meu nome é Ana e tenho 30 anos.
if (p.EhMaiorDeIdade())
Console.WriteLine($"{p.Nome} pode dirigir.");
O método EhMaiorDeIdade devolve um bool calculado a partir do próprio Idade do objeto, e Apresentar executa uma ação usando Nome e Idade. Ambos operam sobre as características do objeto pelo qual são chamados. Essa combinação — características que descrevem o objeto, e métodos que agem sobre elas ou informam sobre elas — é a forma plena de um objeto: uma coisa que é de certo modo e sabe fazer certas coisas, tudo reunido numa unidade coesa. É a promessa da Aula #22, agora completamente cumprida.
A palavra this: o objeto refere-se a si mesmo
Dentro de um método de objeto, às vezes precisamos referir-nos explicitamente ao próprio objeto sobre o qual o método está operando. Para isso existe a palavra especial this (em inglês, "este"), que significa, dentro de um método, "este objeto — aquele pelo qual o método foi chamado". Um uso muito comum de this aparece nos construtores, quando o nome de um parâmetro coincide com o nome de uma característica:
class Pessoa
{
public string Nome { get; set; }
public int Idade { get; set; }
public Pessoa(string nome, int idade)
{
this.Nome = nome; // 'this.Nome' é a property do objeto; 'nome' é o parâmetro
this.Idade = idade;
}
}
Aqui, o parâmetro se chama nome (minúsculo) e a property se chama Nome (maiúsculo), então a distinção já existiria pela convenção de maiúsculas. Mas this.Nome deixa explícito que estamos falando da característica deste objeto, distinguindo-a inequivocamente do parâmetro. O this é especialmente necessário quando o parâmetro e a característica têm exatamente o mesmo nome, situação em que, sem ele, haveria ambiguidade:
public Pessoa(string Nome, int Idade) // parâmetros com o mesmo nome das properties
{
this.Nome = Nome; // this.Nome = a property; Nome (sem this) = o parâmetro
this.Idade = Idade;
}
Nesse caso, this.Nome refere-se à property do objeto, enquanto Nome (sem this) refere-se ao parâmetro; sem o this, o C# não saberia distingui-los. Na maior parte do tempo, graças à convenção de maiúsculas para properties e minúsculas para parâmetros, você não precisa do this — mas é importante reconhecê-lo, porque você o verá com frequência em código de outras pessoas, e ele torna explícito, em qualquer situação, que uma característica pertence ao próprio objeto. Pense em this como a forma de o objeto dizer "eu mesmo".
As classes deixaram de ser apenas conjuntos de dados. Um método de objeto opera sobre o estado daquele exemplar específico, acessando seus próprios campos sem precisar recebê-los como parâmetro — é essa proximidade entre dado e comportamento que dá sentido à ideia de objeto.
A palavra this tornou explícito o mecanismo por trás disso: dentro de um método, ela designa o objeto sobre o qual o método foi chamado. Na maior parte do tempo ela é opcional, porque o C# a subentende; ela se torna necessária quando um parâmetro tem o mesmo nome de um campo e é preciso distinguir um do outro sem ambiguidade.
Fontes e leituras recomendadas
- Métodos de instância — a referência oficial sobre métodos que pertencem a objetos; a base desta aula.
- A palavra-chave this — o significado e os usos de
thispara referir-se ao objeto atual. - Membros de instância versus estáticos — a distinção entre o que pertence ao objeto e o que pertence à classe, para contexto.
- Objetos com estado e comportamento — como características e métodos se combinam num objeto.
- Boas práticas em métodos de objeto — orientações sobre projetar comportamentos claros e coesos.
Exercícios
Exercício 1
Adicione à classe Produto (com properties Nome, Preco, Estoque) dois métodos de objeto: Vender(int quantidade), que reduz o estoque (recusando se não houver estoque suficiente), e Repor(int quantidade), que aumenta o estoque. Crie um produto e teste os dois comportamentos.
Ver resposta
✓ Resposta: Exemplo:
class Produto
{
public string Nome { get; set; }
public int Estoque { get; set; }
public Produto(string nome, int estoque) { Nome = nome; Estoque = estoque; }
public void Vender(int quantidade)
{
if (quantidade > Estoque)
Console.WriteLine("Estoque insuficiente.");
else
{
Estoque = Estoque - quantidade;
Console.WriteLine($"Vendidos {quantidade}. Estoque: {Estoque}");
}
}
public void Repor(int quantidade)
{
Estoque = Estoque + quantidade;
Console.WriteLine($"Repostos {quantidade}. Estoque: {Estoque}");
}
}
Vender reduz o estoque (com verificação de suficiência) e Repor o aumenta, ambos operando sobre o Estoque do próprio objeto.
Exercício 2
Crie uma classe Contador com uma property Valor (iniciada em 0 pelo construtor) e três métodos: Incrementar(), Decrementar() e Zerar(), que modificam o Valor do objeto. Crie um contador, chame os métodos em sequência, e exiba o valor após cada chamada.
Ver resposta
✓ Resposta: Exemplo:
class Contador
{
public int Valor { get; set; }
public Contador() { Valor = 0; }
public void Incrementar() { Valor = Valor + 1; }
public void Decrementar() { Valor = Valor - 1; }
public void Zerar() { Valor = 0; }
}
Contador c = new Contador();
c.Incrementar(); Console.WriteLine(c.Valor); // 1
c.Incrementar(); Console.WriteLine(c.Valor); // 2
c.Decrementar(); Console.WriteLine(c.Valor); // 1
c.Zerar(); Console.WriteLine(c.Valor); // 0
Cada método modifica o Valor do objeto, e as chamadas em sequência alteram o estado passo a passo.
Exercício 3
Adicione à classe Pessoa um método int AnosAte(int anoFuturo) que devolva quantos anos a pessoa terá em determinado ano futuro (considerando sua idade atual e um ano de referência). Explique como o método usa o estado do próprio objeto para calcular o resultado.
Ver resposta
✓ Resposta: Exemplo:
public int AnosAte(int anoFuturo)
{
int anoAtual = 2026;
return Idade + (anoFuturo - anoAtual);
}
O método usa o estado do próprio objeto — sua property Idade — como base do cálculo: soma à idade atual a quantidade de anos entre o ano de referência e o ano futuro. Como Idade pertence ao objeto pelo qual o método foi chamado, o resultado é específico daquela pessoa; chamado em pessoas de idades diferentes, produz resultados diferentes, pois cada uma tem seu próprio Idade.
Exercício 4
Explique, com suas palavras, o significado da palavra this dentro de um método de objeto. Escreva um construtor de uma classe qualquer em que o this seja necessário (parâmetros com o mesmo nome das properties) e explique o que cada lado da atribuição representa.
Ver resposta
✓ Resposta: Dentro de um método de objeto, this significa "este objeto" — o objeto específico pelo qual o método foi chamado —, permitindo referir-se explicitamente às características do próprio objeto. Exemplo em que é necessário:
public Pessoa(string Nome, int Idade)
{
this.Nome = Nome; // this.Nome = a property do objeto; Nome = o parâmetro
this.Idade = Idade;
}
Aqui os parâmetros têm o mesmo nome das properties. Do lado esquerdo, this.Nome representa a property do objeto (a característica que estamos preenchendo); do lado direito, Nome (sem this) representa o parâmetro (o valor recebido). O this é necessário porque, sem ele, os dois nomes idênticos seriam ambíguos, e o C# não saberia qual é a property e qual é o parâmetro.
Exercício 5
Sem código: um método de objeto como conta.Depositar(500m) opera sobre o saldo daquela conta específica. Explique como o objeto "sabe" sobre qual saldo operar, e por que chamar conta1.Depositar(100m) não afeta o saldo de conta2. Relacione com a ideia de que cada objeto tem suas próprias características.
Ver resposta
✓ Resposta: O objeto "sabe" sobre qual saldo operar porque o método é chamado através de um objeto específico (conta.Depositar(500m)), e, dentro do método, as referências às características (como Saldo) apontam para as características daquele objeto — o que foi usado antes do ponto. Assim, conta1.Depositar(100m) opera sobre o Saldo de conta1, e conta2.Depositar(...) operaria sobre o de conta2, porque cada objeto tem seu próprio conjunto de características, independentes das de outros objetos. Chamar o método em conta1 não afeta conta2 porque são objetos distintos, cada um com seu próprio saldo; o método sempre age sobre o estado do objeto pelo qual foi acionado, e nunca sobre o de outro.