CodeGym /Blogue Java /Random-PT /Classes Java: escrevendo suas próprias classes, construto...
John Squirrels
Nível 41
San Francisco

Classes Java: escrevendo suas próprias classes, construtores

Publicado no grupo Random-PT
Oi! Hoje falaremos sobre classes em Java. Você poderia dizer que as classes formam a base da programação Java. Quando você se torna um programador, quase todo o seu trabalho será escrever suas próprias classes com várias funções. Vamos ver o que isso significa e como funciona. :) Como você sabe, Java é uma linguagem de programação orientada a objetos. Todos os programas consistem em objetos que, de uma forma ou de outra, estão relacionados entre si. Uma classe é, essencialmente, um modelo para um objeto. Ele determina a aparência do objeto e quais funções ele terá. Todo objeto é um objeto de alguma classe. Considere este exemplo muito simples:

public class Cat {

    String name;
    int age;

}
Digamos que estamos escrevendo um programa que envolve gatos por algum motivo (por exemplo, temos uma clínica veterinária que oferece acesso a uma conta online). Criamos uma classe Cat e declaramos duas variáveis ​​nela: String name e int age . Essas variáveis ​​de membro são chamadas de campos. Essencialmente, este é um modelo para todos os gatos que criaremos no futuro. Cada objeto Cat terá duas variáveis: um nome e uma idade.

public class Cat {

    String name;
    int age;

    public static void main(String[] args) {
        Cat smudge = new Cat();
        smudge.age = 3;
        smudge.name = "Smudge";

        System.out.println("We created a cat named " + smudge.name + ". His age is " + smudge.age);
    }

}
Veja como funciona! Criamos um gato, damos a ele um nome e uma idade e exibimos tudo no console. Pedaco de bolo. :) Na maioria das vezes, as aulas descrevem coisas e fenômenos do mundo real. Um gato, uma mesa, uma pessoa, um raio, uma página de livro, uma roda - você criará todas essas coisas em seus programas usando classes individuais. Por enquanto, vamos focar nas variáveis ​​que declaramos na classe Cat . Eles são chamados de campos ou variáveis ​​de instância. O nome deles realmente diz tudo. Cada instância (ou objeto) da classe Cat terá essas variáveis. Cada gato que criamos terá sua própria variável de nome e sua própria idadevariável. Isso faz sentido - é basicamente como acontece com gatos de verdade. :) Além das variáveis ​​de instância, também existem variáveis ​​de classe (variáveis ​​estáticas). Vamos terminar nosso exemplo:

public class Cat {

    String name;
    int age;

    static int count = 0;

    public static void main(String[] args) {
        Cat smudge = new Cat();
        smudge.age = 3;
        smudge.name = "Smudge";
        count++;

        Cat fluffy = new Cat();
        fluffy.age = 5;
        fluffy.name = "Fluffy";
        count++;

        System.out.println("We created a cat named " + smudge.name + ". His age is " + smudge.age);
        System.out.println("We created a cat named " + fluffy.name + ". His age is " + fluffy.age);

        System.out.println("Total number of cats = " + count);
    }
}
Saída do console: criamos um gato chamado Smudge. Ele tem 3 anos. Criamos um gato chamado Fluffy. Sua idade é 5 Número total de gatos = 2 Agora nossa classe tem uma nova variável chamada contagem. É responsável por contar os gatos criados. Toda vez que criamos um gato no mainmétodo, aumentamos essa variável em 1. Essa variável é declarada usando a palavra-chave static. Isso significa que pertence à classe, não a um objeto específico da classe. O que, claro, faz sentido: o nome de cada gato pertence àquele gato específico, mas precisamos de um contador de gato que se aplique a todos eles. É exatamente isso que a palavra-chave static realiza: torna a variável count uma única variável para todos os gatos. Nota: quando exibimos a variável, não estamos usando smudge.count ou fluffy.count. Não pertence a Smudge ou Fluffy; ele pertence a toda a classe Cat . É por isso que é simplesmente contar. Você também pode escrever Cat.count. Isso também seria correto. Ao exibir a variável name, não faríamos o seguinte:

public class Cat {

    String name;
    int age;

    static int count = 0;

    public static void main(String[] args) {
        Cat smudge = new Cat();
        smudge.age = 3;
        smudge.name = "Smudge";
        count++;

        System.out.println("We created a cat named " + name + ". His age is " + smudge.age);

        System.out.println("Total number of cats = " + count);
    }
}
Isso é um erro! Cada gato tem seu próprio nome. O compilador fica confuso aqui. "Enviar um nome para o console? Nome de quem?" :/"

Métodos

Além das variáveis, cada classe possui métodos. Falaremos sobre eles com mais detalhes em uma lição separada, mas os princípios gerais são bem simples. Os métodos definem a funcionalidade de sua classe, ou seja, o que os objetos de sua classe podem fazer. Você já está familiarizado com um desses métodos: o método main() . Mas, como você deve se lembrar, o método main é estático, o que significa que pertence à classe inteira (a lógica é a mesma das variáveis). No entanto, métodos não estáticos padrão só podem ser chamados em objetos específicos que criamos. Por exemplo, se quisermos escrever uma classe cat, precisamos saber quais funções um cat em nosso programa deve ter. Com base nessa premissa, vamos escrever alguns métodos para nosso gato:

public class Cat {

    String name;
    int age;

    public void sayMeow() {
        System.out.println("Meow!");
    }

    public void jump() {
        System.out.println("Pounce!");
    }

    public static void main(String[] args) {
        Cat smudge = new Cat();
        smudge.age = 3;
        smudge.name = "Smudge";

        smudge.sayMeow();
        smudge.jump();

    }
}
Confira! Agora nossa classe está muito mais próxima de se parecer com um gato! Agora não temos apenas um gato com nome ("Smudge") e idade (3). Ele também pode dizer miau e pular! Que tipo de gato seria sem essa "funcionalidade"? :) Estamos pegando um objeto específico (smudge) e chamando seus métodos sayMeow() e jump() . Vejamos o console: Miau! Atacar! Um gato de verdade! :)

Criando suas próprias classes. Abstração

No futuro, você terá que escrever suas próprias classes. O que você precisa observar ao escrevê-los? Se estivermos falando de variáveis, você precisará fazer uso de algo chamado abstração. Abstração é um dos quatro princípios básicos da programação orientada a objetos. Significa extrair as características mais importantes e significativas de um item e, inversamente, descartar aquelas que são menores ou insignificantes. Por exemplo, vamos criar um arquivo para funcionários de uma empresa. Para criar objetos de funcionário, escrevemos um Employeeaula. Quais características são descritores importantes de um funcionário para o arquivo de nossa empresa? Nome, data de nascimento, SSN e ID do funcionário. Mas é improvável que precisemos da altura, cor dos olhos ou cor do cabelo do funcionário para o registro do funcionário da empresa. As empresas não precisam dessas informações. Assim, na classe Employee , declaramos as seguintes variáveis: String name , int age , int socialSecurityNumber e int employeeId. E deixamos de fora informações desnecessárias (como a cor dos olhos). Em outras palavras, criamos uma abstração. No entanto, se estivermos fazendo um arquivo para agências de modelos, a situação muda drasticamente. A altura, a cor dos olhos e a cor do cabelo de uma modelo são características importantes, mas seu SSN é absolutamente irrelevante para nós. Então, na classe Model , precisamos criar as seguintes variáveis: String height , String hair , String eyes . É assim que a abstração funciona – é fácil! :)

Construtores

Vamos voltar ao nosso exemplo do gato.

public class Cat {

    String name;
    int age;

    public static void main(String[] args) {
        Cat smudge = new Cat();

        System.out.println("Here the program does something for 2 hours...");

        smudge.age = 3;
        smudge.name = "Smudge";

    }
}
Examine este código e tente descobrir o que há de errado com nosso programa. Nosso programa teve um gato sem nome ou idade por 2 horas! Claro, isso é inerentemente errado. O banco de dados da clínica veterinária não deve incluir gatos sem informações. Atualmente, nosso gato está à mercê do programador. Esperamos que ele não se esqueça de especificar um nome e idade, e que tudo ficará bem. Se ele esquecer, o banco de dados terá um problema: gatos sem nome. Como podemos resolver este problema? Devemos de alguma forma impedir que gatos sejam criados sem nome e idade. É aqui que os construtores vêm em socorro. Vamos dar um exemplo:

public class Cat {

    String name;
    int age;

    // Constructor for the Cat class
    public Cat(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public static void main(String[] args) {

        Cat smudge = new Cat("Smudge", 5);
    }
}
Essencialmente, um construtor é um modelo para objetos de uma classe. Nesse caso, indicamos que dois argumentos, um String e um int , devem ser especificados para cada objeto cat . Se tentarmos criar um gato sem nome agora, não vai funcionar.

public class Cat {

    String name;
    int age;

    public Cat(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public static void main(String[] args) {

        Cat smudge = new Cat(); // Error!
    }
}
Agora que a classe tem um construtor, o compilador Java sabe como os objetos devem se parecer e não permite que objetos sejam criados sem especificar os argumentos. Agora, vamos investigar a palavra-chave this, que você vê dentro do construtor. É simples também. A palavra-chave this é para indicar um objeto em particular. O código no construtor

public Cat(String name, int age) {
    this.name = name;
    this.age = age;
}
pode ser interpretado quase literalmente: "O nome deste gato (o que estamos criando) = o argumento passado para o parâmetro name do construtor. A idade deste gato (o que estamos criando) = o argumento passado para o parâmetro do construtor parâmetro de idade." Após a execução do construtor, você pode verificar se todos os valores necessários foram atribuídos ao nosso gato:

public class Cat {

    String name;
    int age;

    public Cat(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public static void main(String[] args) {

        Cat smudge = new Cat("Smudge", 5);
        System.out.println(smudge.name);
        System.out.println(smudge.age);
    }
}
Saída do console: Smudge 5 Quando o construtor foi chamado:

Cat smudge = new Cat("Smudge", 5);
Isso é o que realmente aconteceu internamente:

this.name = "Smudge";
this.age = 5;
E os valores dos argumentos passados ​​para o construtor foram atribuídos ao objeto smudge (é a isso que se refere neste caso). Na verdade, mesmo que você não declare nenhum construtor em uma classe, ela ainda chamará um construtor! Mas como isso é possível? О_О Porque, todas as classes Java têm um chamado construtor padrão. Ele não requer nenhum argumento, mas é invocado toda vez que você cria qualquer objeto de qualquer classe.

public class Cat {

    public static void main(String[] args) {

        Cat smudge = new Cat(); // The default constructor is invoked here
    }
}
À primeira vista, isso pode não ser óbvio. Criamos um objeto, e daí? Onde o construtor está fazendo alguma coisa aqui? Para vê-lo, vamos escrever explicitamente um construtor vazio para a classe Cat . Dentro dele, enviaremos alguma frase para o console. Se a frase for exibida, o construtor foi invocado.

public class Cat {

    public Cat() {
        System.out.println("A cat has been created!");
    }

    public static void main(String[] args) {

        Cat smudge = new Cat(); // The default constructor is invoked here
    }
}
Saída do console: Um gato foi criado! Aí está a confirmação. O construtor padrão está sempre presente de forma invisível em suas classes. Mas você precisa saber mais uma coisa sobre isso. O construtor padrão é eliminado de uma classe quando você cria um construtor com argumentos. Na verdade, já vimos a prova disso acima. Foi neste código:

public class Cat {

    String name;
    int age;

    public Cat(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public static void main(String[] args) {

        Cat smudge = new Cat(); // Error!
    }
}
Não poderíamos criar um Cat sem nome e idade, porque declaramos um construtor Cat com parâmetros string e int. Isso fez com que o construtor padrão desaparecesse imediatamente da classe. Portanto, lembre-se de que, se precisar de vários construtores em sua classe, incluindo um construtor sem argumentos, você terá que declará-lo separadamente. Nossa clínica quer fazer boas ações e ajudar gatinhos sem-teto cujos nomes e idades são desconhecidos. Então nosso código deve ficar assim:

public class Cat {

    String name;
    int age;

    // For cats with owners
    public Cat(String name, int age) {
        this.name = name;
        this.age = age;
    }

    // For street cats
    public Cat() {
    }

    public static void main(String[] args) {
        
        Cat smudge = new Cat("Smudge", 5);
        Cat streetCat = new Cat();
    }
}
Agora que especificamos um construtor padrão explícito, podemos criar os dois tipos de gatos. No construtor, você pode atribuir valores diretamente. Você não precisa sempre tirá-los de argumentos. Por exemplo, poderíamos rotular todos os gatos de rua no banco de dados usando "Street cat No. <count>" como modelo. :

public class Cat {

    String name;
    int age;

    static int count = 0;

    public Cat() {
        count++;
        this.name = "Street cat No. " + count;
    }

    public Cat(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public static void main(String[] args) {

        Cat streetCat1 = new Cat();
        Cat streetCat2 = new Cat();
        System.out.println(streetCat1.name);
        System.out.println(streetCat2.name);
    }
}
Temos uma variável de contagem , que conta nossos gatos de rua. Cada vez que o construtor padrão é executado, aumentamos a contagem em 1 e anexamos esse número ao nome do gato. A ordem dos argumentos é muito importante para os construtores. Vamos trocar os argumentos name e age passados ​​para nosso construtor.

public class Cat {

    String name;
    int age;

    public Cat(int age, String name) {
        this.name = name;
        this.age = age;
    }

    public static void main(String[] args) {

        Cat smudge = new Cat("Smudge", 10); // Error!
    }
}
Ocorreu um erro! O construtor estipula claramente que, quando um objeto Cat é criado, deve ser passado um número e uma string, nesta ordem. Portanto, nosso código não funciona. Certifique-se de lembrar e respeitar esta regra ao declarar suas próprias classes:

public Cat(String name, int age) {
    this.name = name;
    this.age = age;
}

public Cat(int age, String name) {
    this.age = age;
    this.name = name;
}
Estes são dois construtores totalmente diferentes! Agora, conclua algumas tarefas para solidificar sua compreensão do material. :)
  1. Museu de Antiguidades.

    Sua tarefa é projetar uma classe de Artefato .
    Existem três tipos de artefatos mantidos no museu.
    Sobre o primeiro tipo nada sabemos, exceto o número de série atribuído pelo museu (por exemplo: 212121).
    Para o segundo tipo, conhecemos o número de série e a cultura que o criou (por exemplo: 212121, "astecas").
    Para o terceiro tipo, conhecemos o número de série, a cultura que o criou e o século em que foi criado (por exemplo: 212121, "Aztecs", 12).

    Crie uma classe de artefato que descreva as antiguidades mantidas no museu e escreva o conjunto necessário de construtores para a classe. Em seguida, no método main() , crie um artefato de cada tipo.

    
    public class Artifact {
        
        // Write your code here
    
        public static void main(String[] args) {
            // Write your code here
        }
    }
    
  2. Site de encontros

    Vamos criar um banco de dados de usuários para um site de encontros.
    Mas aqui está o problema: você esqueceu a ordem exigida dos argumentos e não há documentação técnica disponível.
    Projete uma classe User , que terá os seguintes campos: name ( String ), age ( short ) e height ( int ).
    Crie o número apropriado de construtores, para que o nome, a idade e a altura possam ser especificados em qualquer ordem.

    
    public class User {
    
        String name;
        short age;
        int height;
    
        // Write your code here
    
        public static void main(String[] args) {
            
        }
    }
    
Para reforçar o que você aprendeu, sugerimos que você assista a uma vídeo aula do nosso Curso de Java
Comentários
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION