Java O que é POO

Java é uma linguagem orientada a objetos. Isso quer dizer que os programas são organizados em torno de "coisas" do mundo do problema (alunos, contas, produtos, pedidos), cada uma com os seus dados e as suas ações. Esta aula apresenta a ideia, sem pressa; as próximas ensinam cada peça em detalhe.

Você vai aprender
  • Que problema a programação orientada a objetos (POO) resolve.
  • A diferença entre classe (o molde) e objeto (cada coisa feita com o molde).
  • O que são estado (os dados de um objeto) e comportamento (o que ele sabe fazer).
  • Que você já usa objetos desde o Nível 1 (String, Scanner).
  • A ideia dos quatro pilares: encapsulamento, herança, polimorfismo e abstração.

O problema: dados espalhados

A Ana quer guardar, para cada aluno, o nome e duas notas, e calcular a média. Com o que você aprendeu até aqui (arrays e métodos), a solução natural é usar um array para cada informação:

public class Main {
    public static void main(String[] args) {
        String[] nomes = {"Bruno", "Carla", "Davi"};
        double[] notas1 = {8.0, 9.5, 5.0};
        double[] notas2 = {7.0, 9.0, 6.0};

        for (int i = 0; i < nomes.length; i++) {
            double media = (notas1[i] + notas2[i]) / 2;
            System.out.println(nomes[i] + ": média " + media);
        }
    }
}
$ javac Main.java && java Main
Bruno: média 7.5
Carla: média 9.25
Davi: média 5.5

Funciona. Mas repare como as informações de um aluno estão espalhadas: o nome do Bruno está em nomes[0], as notas dele em notas1[0] e notas2[0]. Nada no código diz que essas três posições formam "o Bruno"; é só um combinado de que o índice 0 de cada array é a mesma pessoa. Agora imagine:

  • A Ana acrescenta e-mail, telefone, turma e faltas: são sete arrays andando juntos.
  • Ela ordena os nomes em ordem alfabética, mas esquece de reordenar as notas: o Bruno fica com as notas da Carla, sem nenhum erro na tela.
  • Ela quer um método mostrarAluno: precisa passar o índice e todos os arrays como parâmetros.

O que falta é um jeito de dizer ao Java: "um aluno é uma coisa só, que tem nome, nota1 e nota2, e sabe calcular a própria média". É exatamente isso que a orientação a objetos oferece.


A ideia: classe é o molde, objeto é o que sai dele

Pense na secretaria da escola da Ana. Existe uma ficha de matrícula em branco, impressa igual para todo mundo, com os campos "Nome", "Nota 1" e "Nota 2". Cada aluno que se matricula recebe uma ficha preenchida, com os seus dados.

Na secretariaEm JavaNo exemplo
O modelo da ficha (em branco)ClasseAluno
Os campos da fichaAtributos (ou campos)nome, nota1, nota2
Uma ficha preenchidaObjeto (ou instância)o aluno Bruno, a aluna Carla
"Imprimir uma ficha nova"Criar um objeto com newnew Aluno()
O que a ficha "sabe fazer" (calcular a média do aluno)Métodosmedia()

Outra comparação muito usada: a forma de biscoito é a classe; cada biscoito é um objeto. A forma define o formato de todos, mas cada biscoito é um biscoito diferente, que pode ter cobertura diferente. E a forma não se come: você não usa a classe diretamente, usa os objetos criados com ela.

Em código, a classe Aluno e dois objetos dela ficam assim:

class Aluno {
    String nome;
    double nota1;
    double nota2;

    double media() {
        return (nota1 + nota2) / 2;
    }
}

public class Main {
    public static void main(String[] args) {
        Aluno bruno = new Aluno();
        bruno.nome = "Bruno";
        bruno.nota1 = 8.0;
        bruno.nota2 = 7.0;

        Aluno carla = new Aluno();
        carla.nome = "Carla";
        carla.nota1 = 9.5;
        carla.nota2 = 9.0;

        System.out.println(bruno.nome + ": média " + bruno.media());
        System.out.println(carla.nome + ": média " + carla.media());
    }
}
$ javac Main.java && java Main
Bruno: média 7.5
Carla: média 9.25
$ ls
Aluno.class  Main.class  Main.java        « o javac gerou um .class para cada classe

Você vai estudar cada linha nas próximas aulas. Por enquanto, uma leitura geral:

class Aluno { … }
Declara a classe Aluno: o molde. Ela fica no mesmo arquivo, antes da Main; em Classes e Objetos você verá como separá-la em outro arquivo.
String nome; double nota1; double nota2;
Os atributos: o que todo aluno tem. São variáveis declaradas na classe, fora dos métodos, e sem static (veja Atributos).
double media() { … }
Um método do aluno, também sem static. Ele usa nota1 e nota2 do próprio aluno (veja Métodos de Objeto).
Aluno bruno = new Aluno();
Cria um objeto novo da classe Aluno (uma ficha em branco) e guarda-o na variável bruno. O tipo da variável é a própria classe.
bruno.nome = "Bruno";
O ponto quer dizer "de": "o nome do bruno recebe Bruno". Preenche um campo da ficha.
bruno.media()
Pede ao objeto bruno que calcule a média dele. A mesma chamada em carla usa as notas da Carla.

Agora tudo o que é do Bruno está junto, dentro de um objeto só. Não há índice para combinar, nem arrays para manter em ordem.

Missão: crie um terceiro aluno, davi, com notas 5.0 e 6.0, e mostre a média dele no mesmo formato: Davi: média 5.5. Siga o modelo do Bruno.

class Aluno {
    String nome;
    double nota1;
    double nota2;

    double media() {
        return (nota1 + nota2) / 2;
    }
}

public class Main {
    public static void main(String[] args) {
        Aluno bruno = new Aluno();
        bruno.nome = "Bruno";
        bruno.nota1 = 8.0;
        bruno.nota2 = 7.0;

        System.out.println(bruno.nome + ": média " + bruno.media());
    }
}
class Aluno {
    String nome;
    double nota1;
    double nota2;

    double media() {
        return (nota1 + nota2) / 2;
    }
}

public class Main {
    public static void main(String[] args) {
        Aluno bruno = new Aluno();
        bruno.nome = "Bruno";
        bruno.nota1 = 8.0;
        bruno.nota2 = 7.0;

        Aluno davi = new Aluno();
        davi.nome = "Davi";
        davi.nota1 = 5.0;
        davi.nota2 = 6.0;

        System.out.println(bruno.nome + ": média " + bruno.media());
        System.out.println(davi.nome + ": média " + davi.media());
    }
}

Estado e comportamento

Todo objeto tem duas coisas:

  • Estado: o que ele é ou tem agora. São os valores dos atributos. O estado do Bruno é "nome Bruno, nota1 8.0, nota2 7.0". Se a Ana corrige uma nota, o estado muda.
  • Comportamento: o que ele sabe fazer. São os métodos. Todo aluno sabe calcular a sua média.
CoisaEstado (atributos)Comportamento (métodos)
Alunonome, notas, turmacalcular a média, dizer se foi aprovado
Conta bancáriatitular, saldodepositar, sacar, mostrar extrato
Fruta da loja da Ananome, preço, estoqueaplicar desconto, vender uma unidade
Lâmpadaligada ou desligada, potêncialigar, desligar

Uma dica para descobrir as classes de um problema: os substantivos (aluno, conta, fruta) costumam virar classes; as características deles viram atributos; os verbos (depositar, vender) viram métodos.


Você já usa objetos

Desde o Nível 1, toda String é um objeto. A classe String foi escrita pelos criadores do Java; cada texto que você cria é um objeto dela, com o seu próprio estado (as letras) e os métodos da classe:

public class Main {
    public static void main(String[] args) {
        String fruta = "banana";
        String outra = "maçã";
        System.out.println(fruta.length());
        System.out.println(outra.length());
        System.out.println(fruta.toUpperCase());
    }
}
$ javac Main.java && java Main
6          « o comportamento length() aplicado ao estado "banana"
4          « o mesmo método, outro objeto, outro resultado
BANANA

É a mesma estrutura do bruno.media(): objeto.metodo(). O Scanner de Ler do Teclado também: new Scanner(System.in) cria um objeto, e teclado.nextInt() chama um método dele. A diferença, a partir de agora, é que você vai escrever as suas próprias classes.


Programar "com procedimentos" × "com objetos"

Procedural (o que você fez até aqui)Orientado a objetos
OrganizaçãoDados de um lado (variáveis, arrays), funções do outro (métodos static)Dados e as ações sobre eles juntos, dentro de cada objeto
Pergunta que guia"Quais passos o programa executa?""Quais coisas existem e o que cada uma faz?"
Chamada típicamedia(notas1[i], notas2[i])aluno.media()
Bom paraProgramas pequenos, scripts, cálculosSistemas que crescem, com muitas "coisas" diferentes

Uma não substitui a outra: dentro dos métodos de um objeto você continua usando if, laços e variáveis do jeito que aprendeu. A POO é uma forma de organizar o programa em partes maiores.


Os quatro pilares (só a ideia)

Quatro ideias sustentam a orientação a objetos. Você não precisa dominá-las agora: cada uma tem a sua aula. O importante é saber que existem e reconhecer os nomes.

1. Encapsulamento: esconder os detalhes

O objeto protege os seus dados e só deixa mexer neles pelos métodos que ele oferece. Pense no caixa eletrônico: você não abre o cofre e pega o dinheiro; você pede um saque, e a máquina confere o saldo antes. Em Java, isso se faz com private e métodos get/set. Aulas: Modificadores de Acesso e Encapsulamento.

2. Herança: aproveitar uma classe para criar outra

Uma classe pode herdar tudo de outra e acrescentar o que é seu. Um AlunoBolsista é um Aluno com um campo a mais, o valor da bolsa; não é preciso reescrever nome, notas e média. Aula: Herança.

3. Polimorfismo: a mesma mensagem, respostas diferentes

"Poli" = muitas, "morfo" = formas. Objetos diferentes podem responder ao mesmo pedido cada um do seu jeito. Se a loja da Ana pede calcularPreco() a uma fruta vendida por quilo e a uma vendida por unidade, cada uma calcula à sua maneira, e quem pediu não precisa saber qual é qual. Aula: Polimorfismo.

4. Abstração: ficar só com o que importa

Um modelo nunca copia a realidade inteira: ele escolhe o que é relevante para o programa. Para a secretaria, um aluno tem nome e notas; a cor do cabelo dele não interessa. A abstração também aparece como "contratos" que dizem o que fazer sem dizer como. Aulas: Classes Abstratas e Interfaces.

PilarEm uma frasePalavras do JavaAula
EncapsulamentoEsconder os dados e expor ações segurasprivate, public, get/setEncapsulamento
HerançaUma classe reaproveita outra e acrescentaextends, superHerança
PolimorfismoMesmo pedido, comportamento conforme o objeto@OverridePolimorfismo
AbstraçãoModelar só o essencial; contratos sem detalhesabstract, interfaceClasses Abstratas

Vocabulário

Você vai ver estes termos em livros, vagas de emprego e documentação. Vários são sinônimos:

TermoSignificadoTambém chamado
ClasseO molde, a descrição de um tipo de coisatipo
ObjetoUma coisa concreta criada a partir da classeinstância
InstanciarCriar um objeto (new Aluno())criar uma instância
AtributoVariável declarada na classe, que cada objeto temcampo, propriedade, variável de instância (field)
MétodoAção que o objeto sabe fazercomportamento, operação
EstadoOs valores atuais dos atributos de um objeto
ReferênciaO "endereço" de um objeto, guardado numa variávelveja Classes e Objetos

Quando dá errado

Os primeiros erros com objetos quase sempre vêm de confundir a classe (o molde) com um objeto (uma ficha preenchida).

Usar a classe no lugar do objeto: "non-static … cannot be referenced from a static context"
class Aluno {
    String nome;
    double nota1;
    double nota2;

    double media() {
        return (nota1 + nota2) / 2;
    }
}

public class Main {
    public static void main(String[] args) {
        Aluno.nome = "Bruno";
        System.out.println(Aluno.media());
    }
}
$ javac Main.java
Main.java:13: error: non-static variable nome cannot be referenced from a static context
        Aluno.nome = "Bruno";
             ^
Main.java:14: error: non-static method media() cannot be referenced from a static context
        System.out.println(Aluno.media());
                                ^
2 errors

O que aconteceu: Aluno.nome é como escrever o nome na ficha em branco, o modelo. O Java pergunta: o nome de qual aluno? Atributos e métodos sem static pertencem a cada objeto, não à classe.

Como resolver: crie um objeto e use a variável dele: Aluno bruno = new Aluno(); bruno.nome = "Bruno";.

Esquecer o new: "cannot find symbol … method Aluno()"
$ javac Main.java
Main.java:7: error: cannot find symbol
        Aluno bruno = Aluno();
                      ^
  symbol:   method Aluno()
  location: class Main
1 error

O que aconteceu: sem o new, Aluno() parece a chamada de um método chamado Aluno, que não existe.

Como resolver: Aluno bruno = new Aluno();. O new é o que cria o objeto.

Duas classes public no mesmo arquivo
$ javac Main.java
Main.java:1: error: class Aluno is public, should be declared in a file named Aluno.java
public class Aluno {
       ^
1 error

O que aconteceu: num arquivo .java, só uma classe pode ser public, e ela precisa ter o mesmo nome do arquivo. Aqui, Main.java tinha public class Aluno e public class Main.

Como resolver: tire o public de Aluno (como nos exemplos desta aula) ou mova a classe para um arquivo Aluno.java. As duas formas estão em Classes e Objetos.


Missão final: a classe Fruta

Missão: a classe Fruta já está pronta, com os atributos nome e preco e o método mostrar(). No main, crie dois objetos: uma maçã de 7.9 e uma banana de 3.5, e chame mostrar() em cada um.

class Fruta {
    String nome;
    double preco;

    void mostrar() {
        System.out.println(nome + ": R$ " + preco);
    }
}

public class Main {
    public static void main(String[] args) {
        // crie a maçã e a banana aqui

    }
}
class Fruta {
    String nome;
    double preco;

    void mostrar() {
        System.out.println(nome + ": R$ " + preco);
    }
}

public class Main {
    public static void main(String[] args) {
        Fruta maca = new Fruta();
        maca.nome = "maçã";
        maca.preco = 7.9;

        Fruta banana = new Fruta();
        banana.nome = "banana";
        banana.preco = 3.5;

        maca.mostrar();
        banana.mostrar();
    }
}

Exercícios

1. Molde ou coisa?

Como se chama o "molde" que descreve como são todos os alunos?

2. Criar um objeto

Complete para criar um novo objeto da classe Conta:

Conta minha = ;

3. Os dados do objeto

Como se chama o conjunto dos valores atuais dos atributos de um objeto?

4. Na loja da Ana, "fruta" tem nome e preço e sabe aplicar desconto. O que é "aplicar desconto"?

5. Quantos objetos Aluno existem depois de Aluno a = new Aluno(); Aluno b = new Aluno(); Aluno c = new Aluno();?

6. Qual pilar da POO descreve "um AlunoBolsista aproveita tudo de Aluno e acrescenta a bolsa"?


Resumo

  • A POO organiza o programa em objetos que juntam dados e ações, em vez de dados espalhados em arrays paralelos.
  • Classe = o molde (a ficha em branco). Objeto = cada coisa criada com ele, com new (cada ficha preenchida).
  • Estado = os valores dos atributos; comportamento = os métodos.
  • O ponto liga o objeto ao que é dele: bruno.nome, bruno.media(). Você já fazia isso com texto.length().
  • Os quatro pilares: encapsulamento (esconder), herança (reaproveitar), polimorfismo (cada um responde do seu jeito), abstração (só o essencial).
  • Próximo passo: Classes e Objetos, onde você cria classes e objetos linha por linha.