Criar classes e objetos

Objetivos de aprendizagem

Após concluir esta unidade, você estará apto a:

  • Descrever o relacionamento entre uma classe e um objeto.
  • Definir um parâmetro.
  • Explicar as diferenças entre valores de retorno.

Se esta é a sua primeira parada na trilha Criar habilidades de codificação do Apex, você chegou longe demais. Volte um pouco atrás até o módulo Noções básicas do Apex para administradores. Se você já tem o emblema das Noções básicas do Apex para administradores, então está no lugar certo. 

Nas Noções básicas do Apex para administradores, você aprendeu sobre sintaxe, variáveis, coleções e declarações condicionais do Apex. Você também executou alguns exemplos de código no Developer Console. Neste módulo, vamos desenvolver esses conceitos. Vamos começar.

O que significa orientado a objetos?

Se você leu alguma coisa sobre desenvolvimento de software ou codificação, pode ter encontrado o termo orientado a objetos: classes orientadas a objetos, conceitos orientados a objetos, programação orientada a objetos. O que significa orientado a objetos? 

Com relação às linguagens de programação, orientado a objetos significa que o código foca na descrição dos objetos. Um objeto pode ser qualquer coisa que tenha características únicas, como uma pessoa, uma conta ou até uma flor. Antes de você poder entender profundamente o que significa orientado a objeto, há duas coisas que você precisa entender: classes e objetos. 

Classes

Uma classe é um plano. Objetos são baseados em classes. Uma classe define um conjunto de características e comportamentos que são comuns a todos os objetos dessa classe.

Pense numa flor. Ela tem características, como cor e altura, e comportamentos, como crescer e murchar. Em uma classe do Apex, as características são chamadas variáveis e os comportamentos, métodos.

Uma flor única.

Características (variáveis)
Comportamentos (métodos)
color (cor)
Grow (Crescer)
height (altura)
Pollinate (Polinizar)
maxHeight (alturaMáxima)
Wilt (Murchar)
numberOfPetals (númeroDePétalas)

Imagine um jardim. Embora rosas, lírios e margaridas tenham diferentes cores e alturas, elas todas são flores e têm cor e altura.

Uma flor com cor esmaecida representando uma classe, com três pequenas flores abaixo dela representando as instâncias da classe.

Declarar uma classe 

Este código declara (cria) uma classe:

public class Flower { //body of class }

As classes são declaradas usando quatro partes: o modificador de acesso, a palavra-chave “classe”, o nome da classe e o corpo da classe. O corpo (dentro das chaves { } ), é onde os métodos e as variáveis da classe são definidas. 

Modificador de acesso

Um modificador de acesso é uma palavra-chave em uma declaração de método ou classe. O modificador de acesso determina qual outro código do Apex pode ver e usar a classe ou o método. Embora haja outros modificadores de acesso, o public é o mais comum. As classes públicas estão disponíveis para todas as outras classes do Apex dentro da sua organização.  

Métodos

Os métodos são definidos dentro de uma classe. Um método descreve os comportamentos herdados por objetos da classe. Uma classe pode ter um ou mais métodos. A classe Flower (Flor) tem três métodos (comportamentos): grow, pollinate e wilt.

Um método é declarado (criado) conforme o seguinte:

public static Integer wilt(Integer numberOfPetals){ //body of method }

Parâmetros

Quando criamos métodos, nem sempre sabemos todos os valores necessários para executar o código. Muitas vezes, escrevemos um método que realiza uma tarefa e depois escrevemos um segundo método para realizar uma tarefa semelhante, e assim por diante. Depois percebemos que todos os métodos fazem quase a mesma coisa. Eles são duplicatas com pequenas variações. 

Se apenas houvesse uma forma de fornecer entradas variadas para um único método... Calma! Podemos usar parâmetros. Um parâmetro é uma variável que serve como um espaço reservado, esperando para receber um valor. Os parâmetros são declarados de forma semelhante a uma variável, com um tipo de dados acompanhado pelo nome do parâmetro. Na declaração a seguir, o método wilt tem um parâmetro chamado numberOfPetals. (Embora podemos usar qualquer nome de parâmetro que quisermos, é uma boa prática usar nomes que descrevam o valor que o parâmetro representa.) O parâmetro numberOfPetals espera receber um valor cujo tipo de dados é um número inteiro (integer).

<p>public static void wilt (Integer numberOfPetals){</p><p> //body of method</p><p>}</p>

Como chamamos (usamos) o método wilt? Neste exemplo de código, a primeira linha chama (usa) o método e passa (envia) o valor 4. O valor que você passa é chamado de argumento. O argumento (4 neste caso) está entre parênteses após o nome do método.

wilt(4);
public static void wilt(Integer numberOfPetals){
    system.debug(numberOfPetals);
}

Depois que um valor é passado para um método que inclui um parâmetro, o valor do argumento se torna o valor do parâmetro. O parâmetro funciona como uma variável, de modo que você pode manipulá-lo como qualquer outra variável. 

Vejamos a classe Flower.

public class Flower {
    public static void wilt(Integer numberOfPetals){
        if(numberOfPetals >= 1){
            numberOfPetals--;
        }
    }
}

Nas linhas 2 a 6 da classe Flower, o método wilt verifica o valor de numberOfPetals. Se esse número for maior ou igual a 1, então o método wilt diminui (reduz) o numberOfPetals em um. 

Tipos de retorno

Imagine se você está em um restaurante e quer saber se tem um prato sazonal. Você pergunta ao garçom, “Tem salada de verão?” Você espera um tipo de resposta específico, não um número ou uma frase completa, mas “sim” ou “não”. 

Uma declaração de método precisa dizer explicitamente o seu tipo de retorno esperado. Da mesma forma que um argumento precisa corresponder o tipo de dados especificados pelo parâmetro, uma variável retornada precisa corresponder o tipo de retorno especificado pela declaração do método. O tipo do retorno é um tipo de dados específico, como booleano, sequência de caracteres ou conta, ou pode ser void (nulo, nada), como a seguir:

public static void wilt(Integer numberOfPetals){
    system.debug(numberOfPetals);
}

Quando o tipo de retorno do método é void, o método não retorna um valor. Para retornar um valor, substitua void por um tipo de retorno diferente. 

Por exemplo, aqui, o método wilt espera um valor return (resposta) que é um número inteiro.

public static Integer wilt (Integer numberOfPetals){ //body of method}

public static Integer wilt(Integer numberOfPetals){
    if(numberOfPetals >= 1){
        numberOfPetals--;
    }
    return numberOfPetals;
}

Na linha 1, a palavra-chave Integer (imediatamente após public static) indica que o método retorna um valor que é um número inteiro. A linha 5 usa a palavra-chave return, acompanhada do nome de variável numberOfPetals, para retornar o valor resultante numberOfPetals. Quando um método retorna um valor de variável, o tipo de dados da variável deve corresponder ao tipo de retorno que o método declarou. Neste caso, é esperado que o método wilt retorne um valor inteiro e a variável numberOfPetals é um número inteiro. 

Vamos testar os métodos wilt, grow e pollinate. Primeiro, vamos acabar de codificar os métodos.

Escrever os métodos

  1. No Developer Console, clique em File (Arquivo)| New (Novo)| Apex Class (Classe do Apex).
  2. Insira Flower no nome da classe.
  3. Clique em OK.
  4. Na classe Flower.apxc, substitua o código existente por este código:
  5. public class Flower {
        public static Integer wilt(Integer numberOfPetals){
            if(numberOfPetals >= 1){
                numberOfPetals--;
            }
            return numberOfPetals;
        }
        public static void grow(Integer height, Integer maxHeight){
            height = height + 2;
            if(height >= maxHeight){
                pollinate();
            }
        }
        public static void pollinate(){
            System.debug('Pollinating...');
        }
    }
  6. Clique em File (Arquivo) | Save (Salvar).

Agora que você tem uma classe totalmente definida, já está pronto para testá-la. Você só precisa do nome da classe (Flower), os métodos que você quer testar (wilt e grow), e os argumentos exigidos pelo método. Uma vez que o método grow chama (usa) o método pollinate, você não precisa chamar o método pollinate diretamente. O método wilt espera um valor inteiro (para o parâmetro numberOfPetals) e retornará um valor inteiro. Os métodos grow e pollinate não retornam nada. 

Executar os métodos

  1. Clique em Debug (Depurar) | Open Execute Anonymous Window (Abrir janela Executar no modo anônimo).
  2. Na janela Enter Apex Code (Inserir código do Apex), cole este código:
  3. Flower.wilt(4);
    Flower.grow(5, 7);
  4. Selecione Open log (Abrir registro) e clique em Execute (Executar). O log de execução abre, exibindo o resultado da execução do seu código.
  5. Selecione Debug Only (Depurar somente).

O método grow inclui dois parâmetros, height e maxHeight

Flower.grow(5, 7); passa os argumentos 5 (altura é 5 polegadas) e 7 (altura máxima é 7 polegadas) para o método grow. O método grow adiciona 2 à variável height (linha 9) e então verifica o valor da variável height. Se o valor da variável height for maior ou igual ao valor da variável maxHeight, o método grow chama o método pollinate.

O método pollinate não retorna nada porque seu tipo de retorno é void (nulo).

O que aconteceu?

Você deverá ver uma entrada no log de depuração.

Evento: USER_DEBUG. Detalhes: [18]|DEBUG|Pollinating…

O que você espera que aconteça se usar 2 e 6 para os parâmetros de grow? Experimente. 

O que acontece?

Olhando para os logs de depuração, parece que nada. O que está acontecendo é que definir height como 2 e maxHeight como 6 torna a condição na declaração if falsa, fazendo com que o método pollinate não seja executado. 

Objetos

Lembre que a classe Flower é o plano para criar flores. Ela tem as variáveis color, height, maxHeight e numberOfPetals. Essas variáveis são iguais a null (nenhum valor), mas podem ter valores padrão.  

Um objeto é uma instância de uma classe. Da mesma forma que as crianças herdam traços genéticos, como a cor dos olhos e a altura, de seus pais, os objetos herdam variáveis e métodos de suas classes. 



color = null;
height = null;
maxHeight = null;
numberOfPetals = null;
Classe Flower
Flor com tons esmaecidos.


grow()

pollinate()

wilt()
Flor amarela.
Flor vermelha.
Flor rosa.
color = 'yellow';
color ='red';
color = 'pink';
height = 3;
height = 6;
height = 9;
maxHeight = 6;
maxHeight = 8;
maxHeight = 9;
numberOfPetals = 4;
numberOfPetals = 6;
numberOfPetals = 10;
Flower tulip = new Flower();
tulip.grow();

Flower rose = new Flower();
rose.grow();

Flower peony = new Flower();
peony.grow();

O objeto tulip é uma instância da classe Flower. Cada um dos três objetos de flor é uma flor baseada em uma classe Flower. Para criar uma instância chamada tulip, baseada na classe Flower, use esta sintaxe:

Flower tulip = new Flower();

Você pode usar notação de ponto para chamar métodos de um objeto. Basta adicionar .method(); após o nome do objeto. Por exemplo:

tulip.grow();

Agora você sabe que objetos são instâncias de classes. Dentro de uma classe, as variáveis descrevem o objeto, e os métodos definem as ações que o objeto consegue realizar. Você também trabalhou com parâmetros para receber valores passados em uma variável e tipos de retorno, que enviam algo (ou nada, dependendo do tipo de dados) de volta para um método.

Recursos