O que são Métodos?
Métodos são sinônimos de funções, mas o pessoal do Java quis ser diferentão e escolheu outro nome para a mesmíssima coisa. Se você já definiu uma função em Python, C, C++ ou outra linguagem, é praticamente a mesma coisa.
Como definir um método?
Uma definição simples de um método seria algo como:
nivel_acesso tipo_retorno nome_metodo(parametros....) {
/* ... */
return ; // se for void não tem retorno!
}
Por exemplo, podemos definir um método que realiza um cálculo muito complexo de forma muito inteligente da seguinte forma:
public double calculaChopSuey(double x, int y) {
/* código muito perspicaz aqui */
return resultado;
}
public: é um modificador de acesso, indica a visibilidade de um método.
double: o tipo de variável que é retornado pelo método;
entre parentesis: todos os parametros que a função recebe como input
Como escolher o modificador de acesso que preciso??
public
tem a visibilidade pública; todo mundo consegue te acessar, não importa se está em outro package, classe e etc;protected
somente as subclasses ou o mesmo package conseguem acessar;private
somente a própria classe tem acesso, nem mesmo as classes filhas conseguem usar;sem modificador
ao omitir o modificador, será utilizado um modificadordefault
: qualquer um no mesmo package acessam (subclasses podem acessar SE estiverem no mesmo package!)
Por exemplo:
// arquivo: Animal.java
public class Animal {
void falar() { // modificador default!
System.out.println("estou confuso...");
}
}
// arquivo: Gato.java
public class Gato extends Animal {
public static void main(String[] args) {
var agata = new Gato();
agata.falar(); // usa o falar() definido em Animal!
}
}
O Gato consegue “falar” se o método na classe Animal
for: public
, protected
ou default
O Gato não consegue “falar” se o método na classe Animal
for: private
Já se estiverem em packages diferentes…
// arquivo: animal/Animal.java
package animal;
public class Animal {
protected void falar() {
System.out.println("estou confuso...");
}
}
// arquivo: gato/Gato.java
package gato;
import animal.Animal;
public class Gato extends Animal {
public static void main(String[] args) {
var gato = new Gato();
gato.falar(); // printa: estou confuso...
}
}
O Gato consegue “falar” se o método na classe Animal
for: public
ou protected
O Gato não consegue “falar” se o método na classe Animal
for: private
ou default
Sobrescrever um método
O que acontece se eu quiser que meu gato agora solte um miau?
Nesse caso basta você definir um novo método com outros nomes:
...
protected void falarGato()
...
protected void falarCachorro()
...
protected void falarHumano()
...
Dessa forma o código cresce muito e você teria que olhar sempre como um determinado método está definido para utilizar corretamente, facilitando escrever algo errado, trabalhar 2x e introduzir bugs e etc;
Para evitar isso em Java (e outras linguages) você pode mudar o comportamento de um método herdado, basta sobrescrever ele redefinindo do zero:
package gato;
import animal.Animal;
public class Gato extends Animal {
@Override // é opcional, mas recomendado!
protected void falar() {
System.out.println("miaauu");
}
public static void main(String[] args) {
var gato = new Gato();
gato.falar(); // printa: miaauu
}
}
toString
Em Java há um método fundamental chamado toString()
que irá mostrar em formato de string uma representação daquele objeto.
Ele é invocado automaticamente ao “printar” um objeto, como a seguir:
/*packages, imports e definição da classe aqui */
public static void main(String[] args) {
var gato = new Gato();
System.out.println(gato); // printa: gato.Gato@6ff3c5b5
}
É possível sobrescrever este método para printar algo que você queira:
/*packages, imports e definição da classe aqui */
@Override
public String toString() {
return "Olá, eu sou um gato!"
}
public static void main(String[] args) {
var gato = new Gato();
System.out.println(gato); // printa: Olá, eu sou um gato!
}
O método toString() é geralmente sobrescrito para printar algo mais informativo de um objeto de forma legível, como seus atributos, por exemplo.