W3docs

Métodos de Classe em Java

Adicione métodos de instância a uma classe Java para dar comportamento aos objetos e operar sobre seus campos.

Os métodos de uma classe são o que dão comportamento aos seus objetos. Os campos definem o que um objeto é; os métodos descrevem o que ele pode fazer. Até agora, os métodos que você escreveu eram static — utilitários que pertencem à própria classe. Este capítulo trata dos métodos de instância, que pertencem a cada objeto e operam sobre seus campos.

O termo "métodos de classe" em Java é um pouco ambíguo. A maioria dos autores usa-o para se referir a métodos definidos dentro de uma classe — o que inclui os dois tipos. Alguns o utilizam estritamente para designar métodos static (pois estes literalmente pertencem à classe). Abordaremos os métodos de instância aqui, e os métodos static têm um capítulo próprio em Java static.

Um método de instância

Adicione um método ao corpo da classe, sem static, e ele passará a fazer parte de cada instância:

public class Circle {
  double radius;

  double area() {
    return Math.PI * radius * radius;
  }
}

Agora todo Circle que você criar pode responder a area():

Circle c = new Circle();
c.radius = 5;
System.out.println(c.area());   // 78.539...

O corpo lê radius sem qualificação — Java resolve o nome simples como this.radius, o campo do objeto sobre o qual o método foi chamado.

this — o receptor

Todo método de instância tem um parâmetro invisível chamado this, que se refere ao objeto sobre o qual o método foi chamado:

Circle a = new Circle();   a.radius = 2;
Circle b = new Circle();   b.radius = 5;

a.area();    // inside area(), this == a, so this.radius == 2
b.area();    // inside area(), this == b, so this.radius == 5

O mesmo método compilado é executado nos dois casos; o que muda é qual objeto this referencia. O capítulo da palavra-chave this explica quando você precisa escrever this. explicitamente e quando pode omiti-lo.

Métodos que alteram o estado

Um método também pode escrever em campos. Tais métodos são frequentemente chamados de mutadores:

public class Counter {
  int count;

  void increment() {
    count++;            // mutates this.count
  }
  void reset() {
    count = 0;
  }
  int get() {
    return count;
  }
}

Counter c = new Counter();
c.increment(); c.increment(); c.increment();
System.out.println(c.get());   // 3

A mutação por meio de métodos é como os objetos evoluem ao longo do tempo sem que código externo toque diretamente em seus campos. Os métodos que apenas leem um campo e o retornam são o espelho disso — geralmente chamados de acessores ou getters (int get() acima é um exemplo). Rotear leituras e escritas por meio de métodos, em vez de expor os campos diretamente, é a ideia central por trás do encapsulamento: o objeto permanece no controle dos seus próprios dados.

Chamando outros métodos a partir de dentro

Métodos de instância podem chamar outros métodos no mesmo objeto, simplesmente pelo nome:

public class Rectangle {
  double width, height;

  double area()      { return width * height; }
  double perimeter() { return 2 * (width + height); }

  String describe() {
    return "area=" + area() + ", perimeter=" + perimeter();
  }
}

O compilador transforma area() e perimeter() dentro de describe em this.area() e this.perimeter(). Eles chamam os métodos no retângulo sobre o qual describe foi invocado.

Static vs instância — qual usar

A regra prática: o método depende do estado por objeto?

  • Se sim, é um método de instância (sem static).
  • Se não, é static.
public class Math2 {
  public static int squared(int n) {       // pure calculation — static
    return n * n;
  }
}

public class Counter {
  int count;
  public void increment() {                // reads/writes this.count — instance
    count++;
  }
}

Um sinal comum de problema é um método de instância que ignora this completamente — isso é um método static disfarçado. O capítulo Java static aborda os prós e contras.

Chamar um método de instância requer uma instância

Como os métodos de instância leem this, você não pode chamá-los sem um objeto:

Counter.increment();      // ERROR — increment is not static
new Counter().increment(); // fine — increment is called on a fresh Counter (which is then thrown away)

Counter c = new Counter();
c.increment();             // fine — increment is called on c

Este é o erro de compilação mais comum para iniciantes: um método não estático referenciado a partir de um contexto estático (tipicamente dentro de main, que é estático).

Aviso

Se o compilador indicar non-static method increment() cannot be referenced from a static context, você quase certamente chamou um método de instância sem um objeto — por exemplo Counter.increment() em vez de c.increment(). Crie uma instância primeiro e depois chame o método sobre ela.

Sobrecarga e sobrescrita

Os métodos de instância suportam ambas:

  • Sobrecarga (overloading): múltiplos métodos com o mesmo nome mas listas de parâmetros diferentes na mesma classe (abordado em sobrecarga de método).
  • Sobrescrita (overriding): uma subclasse substituindo a versão herdada de um método (abordado em sobrescrita de método).

Você já viu sobrecarga na Parte 5. Sobrescrita é um dos grandes benefícios da herança e aparece em breve.

Corpos de métodos são blocos

O corpo de um método é apenas um bloco de código comum — variáveis declaradas nele são locais à chamada, o fluxo de controle funciona igual a qualquer outro lugar, e você pode retornar cedo. Nada no fato de "estar em uma classe" muda como o corpo é lido. A única capacidade extra é que identificadores simples agora podem se referir aos campos e outros métodos do objeto.

Um exemplo completo

Este exemplo reúne acessores (area, perimeter), um mutador (scale) e um método que chama outros métodos (describe) em uma única classe. Rectangle é declarado como static class apenas para que toda a demonstração caiba em um único arquivo — essa palavra-chave se aplica à classe aninhada, não aos seus métodos de instância, que ainda são executados em um retângulo específico. Observe que escalar r não altera s: cada objeto carrega seu próprio estado.

java— editable, runs on the server

O que vem a seguir

Até agora você criou objetos escrevendo new Dog() e preenchendo os campos linha a linha. Isso é verboso e sujeito a erros — e fácil de esquecer. A solução é um construtor, um método especial que é executado quando o objeto é criado. Continue para o capítulo de construtores.

Prática

Prática
Qual é a diferença entre um método static e um método de instância?
Qual é a diferença entre um método static e um método de instância?
Was this page helpful?