Introdução às aulas: escrevendo suas próprias classes, construtores

pic1
Você poderia dizer que as classes constituem 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 terá. Todo objeto é um objeto de alguma classe.

Considere este exemplo muito simples:

public class Cat {

String name;
int age;

}

Digamos que estejamos 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 Catclasse e declaramos duas variáveis ​​nela: e . Essas variáveis ​​de membro são chamadas de campos .String nameint age

Essencialmente, este é um modelo para todos os gatos que criaremos no futuro. Cada Catobjeto 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);
}

}

É assim que funciona! Criamos um gato, damos a ele um nome e idade e exibimos tudo no console. Pedaco de bolo. 🙂

Na maioria das vezes, as classes descrevem coisas e fenômenos do mundo real.

Um gato, uma mesa, uma pessoa, um raio, uma página de um livro, uma roda – você criará todas essas coisas em seus programas usando classes individuais.

Por enquanto, vamos nos concentrar nas variáveis ​​que declaramos na Catclasse. Eles são chamados de campos ou variáveis ​​de instância . O nome deles realmente diz tudo. Cada instância (ou objeto) da Catclasse terá essas variáveis. Cada gato que criamos terá sua própria namevariável e sua própria agevariável. Isso faz sentido – é basicamente como acontece com gatos reais. 🙂

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. A idade dele é 3

Criamos um gato chamado Fluffy. A idade dele é 5

Número total de gatos = 2

Agora nossa classe tem uma nova variável chamada contagem . É responsável por contar os gatos criados. Cada vez que criamos um gato no mainmétodo, aumentamos essa variável em 1.

Esta 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 a esse gato específico, mas precisamos de um contador de gato que se aplique a todos eles. Isso é exatamente o que a palavra-chave static realiza: torna a variável de contagem 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; pertence a toda a Catclasse. É por isso que é simplesmente contar .

Você também pode escrever Cat.count . Isso também seria correto.

Ao exibir a variável de nome, 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 bastante simples.

Os métodos definem a funcionalidade da sua classe, ou seja, o que os objetos da sua classe podem fazer. Você já está familiarizado com um desses métodos: o método. Mas, como você deve se lembrar, o método é estático, o que significa que pertence a toda a classe (a lógica é a mesma das variáveis).main()main

No entanto, os métodos padrão não estáticos só podem ser chamados em objetos específicos que criamos.

Por exemplo, se quisermos escrever uma classe cat, precisamos saber quais funções um gato 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 perto de se parecer com um gato! Agora não temos apenas um gato com um nome (“Smudge”) e uma idade (3). Ele também pode dizer miau e pular! Que tipo de gato seria sem essa “funcionalidade”? 🙂

Estamos pegando um objeto específico ( mancha ) e chamando seus métodos e .sayMeow()jump()

Vejamos o console:

Miau!

Pounce!

Um gato de verdade! 🙂

Criando suas próprias classes. Abstração

No futuro, você terá que escrever suas próprias aulas. O que você precisa observar ao escrevê-los?

Se estivermos falando sobre 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, deixar de lado aquelas que são menores ou insignificantes.

Por exemplo, vamos criar um arquivo para os funcionários da empresa. Para criar objetos de funcionários, escrevemos uma Employeeclasse. 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 de funcionários da empresa. As empresas não precisam dessas informações.

Assim, na Employeeclasse, declaramos as seguintes variáveis: , , , e . E deixamos de fora informações desnecessárias (como a cor dos olhos). Em outras palavras, criamos uma abstração .String nameint ageint socialSecurityNumberint employeeId

No entanto, se estivermos fazendo um arquivo para agências de modelos, a situação muda drasticamente. A altura, a cor dos olhos e do cabelo de uma modelo são características importantes, mas seu SSN é absolutamente irrelevante para nós.

Assim, na Modelclasse, precisamos criar as seguintes variáveis: , , .String heightString hairString eyes

É assim que a abstração funciona – é fácil! 🙂

Construtores

Voltemos ao nosso exemplo de 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 sem idade .

É aqui que os construtores vêm ao resgate.

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, a Stringe an int, devem ser especificados para cada catobjeto.

Se tentarmos criar um gato sem nome agora, não 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. Também é simples.

A palavra-chave this é para indicar um objeto específico.

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 de nome do construtor . A idade deste gato (o que estamos criando) = o argumento passado para o parâmetro de idade do construtor .”

Depois que o construtor é executado, 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:

mancha

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 smudgeobjeto (é a isso que se refere neste caso).

Na verdade, mesmo se você não declarar nenhum construtor em uma classe, ele ainda chamará um construtor !

Mas como isso é possível? О_О

Porque, todas as classes Java têm um assim chamado construtor padrão . Não aceita nenhum argumento, mas é invocado sempre 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 ver isso, vamos escrever explicitamente um construtor vazio para a Catclasse. Dentro dele, iremos enviar algumas frases para o console. Se a frase for exibida, o construtor foi chamado.

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 invisivelmente presente em suas classes.

Mas você precisa saber mais uma coisa sobre isso.

O construtor padrão é eliminado de uma classe assim que você cria um construtor com argumentos.

Na verdade, já vimos a prova disso acima. Estava 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