Programação Orientada a Objetos com Java
Mapeamento Completo de Teoria, Prática e Transcrições de Sala de Aula (Slides 1 a 50)
Introdução aos Paradigmas e à POO
1.1 O que é um Paradigma?
No contexto da computação, um paradigma de programação representa um estilo, padrão ou modelo de estruturação de programas utilizado para resolver determinados problemas. Funciona como um conjunto lógico e conceitual de regras que guiam e moldam o raciocínio do desenvolvedor na elaboração das soluções.
1.2 Paradigma Estruturado x Paradigma Orientado a Objetos (POO)
Os dois principais paradigmas de desenvolvimento diferem de forma profunda em como enxergam a relação entre os dados e a lógica de processamento:
Paradigma Estruturado
- Ênfase na decomposição em procedimentos e funções: O fluxo de execução é decomposto sequencialmente em blocos de procedimentos e funções.
- Dados e lógica separados em grande parte: Os dados (estruturados ou simples) são frequentemente mantidos de forma independente das funções que os manipulam, embora possam estar relacionados.
- Dificuldade de manutenção em escala: Sistemas complexos e de grande porte podem ter manutenção mais difícil devido a dependências difusas e compartilhamento de dados.
- É vital entender o modelo estruturado (comum no clássico C) para manter sistemas legados vigentes em PHP, ASP clássico e COBOL.
Paradigma Orientado a Objetos
- Ênfase em objetos: Os sistemas de software são pensados como interações lógicas entre conjuntos de objetos ativos.
- Dados e lógica juntos: Atributos (estado) e métodos (ação) coexistem encapsulados de forma íntegra dentro de uma mesma unidade.
- Troca de mensagens: Os objetos realizam chamadas de métodos entre si, preservando sua autonomia de funcionamento.
- Oferece reuso acelerado de código, manutenções pontuais menos invasivas e facilita determinados tipos de modelagem.
1.3 Origem do Conceito: Alan Kay e a Analogia Biológica
A modelagem de orientação a objetos remonta à década de 1960, tendo as linguagens pioneiras Simula e Smalltalk como marcos fundacionais.
Uma das figuras centrais na concepção da POO e criador do Smalltalk, Alan Kay (laureado com o Prêmio Turing em 2003), usou uma brilhante teoria de analogia algébrico-biológica para propor o paradigma:
"O computador ideal deveria funcionar como um organismo vivo, isto é, cada 'célula' (computador ou objeto) comportar-se-ia relacionando-se com outras células a fim de alcançar um objetivo comum, entretanto, funcionando de forma autônoma."
Abstração, Classes e Objetos
2.1 Abstração
A abstração é o processo de selecionar de forma intencional apenas as propriedades relevantes e indispensáveis de uma entidade real para o escopo do seu software, ignorando as demais qualidades desnecessárias.
Exemplo Prático (Foco Veterinário vs. Companheirismo): O mesmo gato pode ser abstraído de formas diferentes. Uma idosa abstrai o gato sob a perspectiva de companheirismo e afeto. Já um médico veterinário abstrai o mesmo gato mapeando aspectos de saúde, vacinas, batimentos cardíacos, peso e tipo de pelagem. Ambos descartam as informações irrelevantes para os seus respectivos objetivos.
2.2 Classes (O Molde)
Uma classe é a representação abstrata de um conceito, funcionando como uma fôrma, molde ou gabarito estrutural de dados. Ela dita a estrutura e os comportamentos lógicos de qualquer elemento daquele tipo, mas não armazena dados físicos de execução por si só.
- Atributos: Variáveis que representam o estado (dados característicos).
- Métodos: Funções que executam os comportamentos lógicos e de controle.
2.3 Objetos (A Instância Concreta)
Um objeto é uma instância concreta de uma classe, criada a partir de seu molde original.
A Analogia da Fôrma de Bolo: A classe funciona como a fôrma de metal. Ela define o formato do bolo (redondo, com furo no meio). Os bolos produzidos (de cenoura, chocolate ou laranja) representam os objetos instanciados, cada um possuindo valores próprios de atributos, mas compartilhando o molde original.
Modelagem UML Conceitual x Instanciação de Objetos
Molde da Classe (UML)
Instâncias na Memória (Objetos)
Caderno de Exercícios de Fixação de Modelagem
Resolva e rascunhe as questões lógicas passadas em aula para treinar a sua mente a projetar sistemas de informação.
a) Cadeira | b) Cavalo | c) Carro
1. Sistema de Gerenciamento de Loja de Roupas (Q30)
2. Sistema de Bilheteria de Cinema (Q31)
3. Sistema de Controle de Frota de Ônibus (Q32)
Introdução à Linguagem Java
3.1 Histórico e Filosofia de Portabilidade
Desenvolvido no início da década de 1990 pela equipe da Sun Microsystems e adquirido em 2010 pela gigante de tecnologia Oracle Corporation, o Java se fundamenta na premissa da portabilidade.
A Revolução Multiplataforma: Embora a portabilidade já fosse possível anteriormente por meio da recompilação do código-fonte para diferentes plataformas, o Java tornou esse processo muito mais prático. A linguagem consolidou o lema "Escreva uma vez, execute em qualquer lugar" (Write once, run anywhere), facilitando o desenvolvimento multiplataforma.
3.2 A Arquitetura de Execução: JDK, JRE e JVM
A mágica multiplataforma do Java ocorre pela divisão de sua infraestrutura técnica de execução em três conceitos vitais:
-
1. JDK (Java Development Kit) | Ferramenta do Desenvolvedor
Kit contendo o compilador
javace ferramentas que traduzem o código legível (.java) para formato intermediário. -
2. Bytecode (.class) | O Formato Intermediário
O compilador gera um arquivo binário intermediário otimizado chamado bytecode (arquivos
.class), independente de máquina física. -
3. JVM (Java Virtual Machine) | O Computador Virtual
Máquina virtual presente em cada sistema operacional que executa o bytecode, interpretando-o e/ou compilando-o via JIT (Just-In-Time) para instruções nativas da plataforma.
3.3 Java versus Python: Uma Análise de Verbosidade
No Python, as estruturas de códigos são leves e curtas; bastando uma linha com print("Olá") para rodar. No Java, o paradigma orientado a objetos exige que o ponto de entrada (o método main) resida obrigatoriamente dentro de uma classe, necessitando de no mínimo 4 ou 5 linhas de estrutura inicial para a mesma ação.
Regras de Sintaxe e Estrutura de Código
4.1 O Esqueleto do Código Java
Em Java, o código deve residir dentro de uma classe estruturada por blocos delimitados por chaves { }. O ponto e vírgula ; é utilizado para encerrar a maioria das declarações de instrução (exceto blocos de controle de fluxo, classes e assinaturas de métodos):
public static void main(String[] args) {
System.out.println("Hello World"); // Ponto e vírgula
} // Chaves delimitando métodos
} // Fim da classe
4.2 Regras Estritas de Nomenclatura
A comunidade global Java adota regras de boas práticas padronizadas:
| Elemento | Padrão Usado | Exemplo |
|---|---|---|
| Classes | PascalCase (Inicial Maiúscula) | ContaBancaria |
| Métodos | camelCase (Inicial Minúscula) | calcularMedia() |
| Variáveis | camelCase | nomeAluno |
| Constantes | MAIÚSCULAS_COM_UNDER | TAXA_JUROS |
Atributos, Tipos de Dados e Instanciação
5.1 Declarando Atributos
Atributos representam as variáveis de estado de um objeto e devem ser declarados dentro da classe, fora dos escopos de métodos.
⚠️ Atenção: Evite abreviações confusas que dificultam o entendimento do código. Utilize nomes claros:
- String n; // Errado, não expressivo
- String nomePaciente; // Correto, altamente legível
5.2 Tipos Primitivos do Java
O Java possui oito tipos primitivos de dados:
| Tipo | Tamanho | Finalidade / Faixa |
|---|---|---|
| boolean | não especificado | Valores booleanos: true ou false (o tamanho de armazenamento não é definido explicitamente pela especificação do Java) |
| byte | 1 byte | Inteiro muito curto (-128 a 127) |
| short | 2 bytes | Inteiro curto |
| char | 2 bytes | Representa uma unidade de código UTF-16 de 16 bits |
| int | 4 bytes | Inteiro padrão de uso comum |
| float | 4 bytes | Ponto flutuante de precisão simples |
| long | 8 bytes | Inteiro de alta capacidade |
| double | 8 bytes | Ponto flutuante de dupla precisão real |
5.3 Primitivos versus Classes Wrappers
Para cada tipo primitivo, o Java fornece uma classe encapsuladora associada chamada Wrapper (com inicial maiúscula):
int codigo;(Primitivo): Armazena diretamente o valor numérico, sendo mais eficiente em consumo de memória e processamento.Integer quantidadeFilial;(Wrapper): É uma classe que encapsula um valor do tipo primitivo correspondente (int) e fornece campos e métodos utilitários (como conversão de textos, constantes de limite, etc.).
5.4 Instanciação em Memória: Referências vs. Heap
Ao declarar uma variável de um tipo de referência, como Pessoa p;, apenas declaramos uma variável capaz de referenciar um objeto do tipo Pessoa. Essa declaração, por si só, não cria nenhum objeto. O objeto é criado quando usamos new, por exemplo, p = new Pessoa();. A referência retornada por new é então atribuída a p.
Se a variável de referência não aponta para nenhum objeto, seu valor padrão é `null`. Qualquer tentativa de acessar um membro de uma referência `null` causará um erro em tempo de execução do tipo `NullPointerException`.
Construtores e a Palavra-Chave 'this'
6.1 O que é um Construtor?
O construtor é um método de características especiais responsável por inicializar e preparar o estado do objeto no momento de sua criação. Ele compartilha obrigatoriamente do mesmo nome da classe e não possui tipo de retorno.
6.2 O Construtor Padrão e a Sobrecarga
Se nenhum construtor for declarado, o compilador cria automaticamente um construtor padrão sem argumentos implícito. No entanto, se um construtor personalizado for inserido, o Java desativa o padrão. Para permitir o uso do construtor sem parâmetros, é obrigatório reinserir o vazio explicitamente.
6.3 O uso do 'this' para Escopo de Dados
A palavra-chave this é usada para referenciar a instância atual do próprio objeto. Ela é crucial para diferenciar e resolver conflitos de escopo entre atributos da instância e parâmetros locais com nomes idênticos.
Desenvolvimento Prático de Aula: A Classe Banco
Acompanhe o passo a passo da classe concebida em sala, aplicando construtores múltiplos e sobrescrita de método para exibição de referências de dados no console.
public class Banco {
// Atributos mapeados
String nome;
String CNPJ;
String endereco;
int codigo; // Tipo primitivo int
Integer quantidadeFilial; // Wrapper Integer
// 1. Construtor Vazio Declarado
public Banco() {
}
// 2. Construtor com Sobrecarga de Parâmetro
public Banco(String nome) {
this.nome = nome; // diferenciação usando o 'this'
}
// 3. Sobrescrita de Exibição Amigável do Objeto
@Override
public String toString() {
return "Banco: " + this.nome + " | Código: " + this.codigo + " | Endereço: " + this.endereco;
}
}
public class App {
public static void main(String[] args) {
// Criação/instanciação de um objeto usando new
Banco banco1 = new Banco("Itaú Unibanco");
// Atribuição de valores diretos
banco1.codigo = 341;
banco1.endereco = "Avenida Paulista, São Paulo";
banco1.CNPJ = "60.701.190/0001-04";
// Exibição amigável formatada graças ao toString()
System.out.println("--- CADASTRADO COM SUCESSO ---");
System.out.println(banco1);
}
}
Prática de Laboratório (Mãos à Obra!)
Desafio Prático: O Objeto "Escalador"
Conforme especificado em aula (Slide 48), implemente a classe Escalador em linguagem Java seguindo a modelagem técnica de regras de negócio.
Requisitos de Especificação:
- Atributos da Classe:
nome(String),cpf(String),tempoExperiencia(int),idade(int),grau(String),guia(boolean),email(String),telefone(String) eclube(String). - Construtores obrigatórios: Implemente um construtor padrão sem argumentos e outro completo recebendo e inicializando todos os dados utilizando
thispara referenciar os atributos da instância atual. - Sobrescrita do método toString(): Formate uma exibição visual completa e organizada de todas as propriedades do Escalador.
- Instanciação: Na classe principal (
App.java), crie dinamicamente pelo menos três objetos de tipoEscaladorcom dados diferentes e exiba-os no console.
// Arquivo: Escalador.java
public class Escalador {
// 1. Atributos da classe
String nome;
String cpf;
int tempoExperiencia;
int idade;
String grau;
boolean guia;
String email;
String telefone;
String clube;
// 2. Construtor vazio
public Escalador() {
}
// 3. Construtor completo utilizando 'this'
public Escalador(String nome, String cpf, int tempoExperiencia, int idade,
String grau, boolean guia, String email, String telefone, String clube) {
this.nome = nome;
this.cpf = cpf;
this.tempoExperiencia = tempoExperiencia;
this.idade = idade;
this.grau = grau;
this.guia = guia;
this.email = email;
this.telefone = telefone;
this.clube = clube;
}
// 4. Sobrescrita do toString()
@Override
public String toString() {
return "Escalador: " + this.nome + " | CPF: " + this.cpf +
" | Idade: " + this.idade + " anos | Grau: " + this.grau +
" | É Guia? " + (this.guia ? "Sim" : "Não") + " | Clube: " + this.clube;
}
}
Mapeamento Encerrado
Este material didático auxiliar encerra-se exatamente no Slide 50 do material original de Estrutura de Dados. Os tópicos subsequentes que abordam os modificadores de acesso e visibilidade de dados em orientação a objetos (public, private, protected) serão abordados a partir da próxima aula.
Materiais Complementares de Apoio
Apresentação de Slides da Disciplina
Acesse o slide de apoio didático estruturado em PDF/PowerPoint, contendo toda a parte visual, esquemas de compilação da JVM e diagramas de classe UML abordados.
Videoaula Inicial: POO Desmistificada
Assista à explicação em vídeo focado no surgimento do paradigma de Orientação a Objetos, integrando os áudios explicativos e as ilustrações do material didático.
Repositório de Código Fonte
Explore, acesse e faça o download de todos os códigos-fonte de exemplo e exercícios estruturados nesta trilha.