Instituto Federal de Mato Grosso do SulNovembro/2021

08. Objetos e Classes
Algoritmos 2
Prof. Rodrigo Duran
Nesta aula vamos:
-
Vamos aprender o que são objetos e classes no paradigma de programação orientado a objetos
Vamos identificar os atributos e métodos que fazem parte de objetos e como os objetos se relacionam para criar sistemas complexos. Vamos aprender a desenhar sistemas declarando classes e seus relacionamentos de herança.
Paradigma Orientado a Objetos (OO)
Um paradigma de programação orienta o design e comportamento de programas em uma determinada linguagem.
O que é um paradigma em programação?
Quando um estilo de programação se distingue de outros, geralmente em termos de características com um comportamento similar, dizemos que esse estilo se caracteriza como um paradigma.
Existem diversos estilos (ou paradigmas) de programação:
- Imperativo: onde o programador fornece ordens (comandos) a serem executados sequencialmente;
- Funcional: onde todos os elementos de programação são funções e variáveis. Programas produzem e consumem valores e a programação é vista em termos de composição e decomposição de valores;
- Declarativo: onde o programador fornece características de determinados atores no programa e o próprio programa fornece um comportamento para esses atores;
- Orientado a objetos: onde o programador modela atores em um sistema como entidades do "mundo" ao nosso redor que conversam através de troca de mensagens.
Obviamente, as linguagens de programação modernas raramente podem ser divididas em paradigmas. A maioria suporta um ou vários paradigmas e frequentemente nós utilizamos vários desses estilos ao desenvolver sistemas.

Orientação a objetos (OO): Princípios Básicos
Apesar do termo OO significar diversas coisas para pessoas diferentes, em geral temos como princípio básico a modelagem do sistema a partir de objetos, valores que combinam dados e procedimentos (ações). Objetos são abstrações de uma entidade, alguma "coisa" no sistema.
- As características (ou atributos) são responsáveis por descrever um determinado objeto.
- Esses procedimentos, chamados de métodos, tem a capacidade de acessar esses dados ocultos do objeto e definem como o objeto pode ser "usado" e que tipo de comportamentos ele possui.
Cabe ao programador decidir quais atributos e métodos serão associados com cada objeto. Tal decisão depende em quais aspectos do domínio (o "Mundo") são relevantes para o problema a ser solucionado.
Veja na imagem ao lado que qualquer "coisa" pode ser um objeto, os quais podem ser associados com dados (atributos) e ações (métodos).
Alguns objetos podem ser muito parecidos -- ou terem o mesmo tipo.

Modelando um domínio como objetos
Geralmente domínios complexos requerem o uso de vários objetos. Esses objetos definem um comportamento pelas suas características, métodos e pela forma como os objetos se relacionam dentro desse domínio.
Por exemplo, ao modelar um sistema de uma disciplina dentro de um determinado curso, o desenvolvedor tem que fazer escolhas das características relevantes desse domínio, bem como esses objetos se relacionam:
- A disciplina contém suas características (atributos) básicas: período, classe, e carga horária. Dentro da disciplina é possível realizar ações (métodos) como: matricular aluno, associar um professor à disciplina, adicionar uma aula e registrar uma nota.
- Veja que nem todos os atributos de uma disciplina são tipos básicos: alguns também são objetos!
- Nesse nosso exemplo uma disciplina está associada a um professor. O professor é um objeto com atributos e métodos.
- Um atributo pode ter vários objetos. Por exemplo, uma disciplina tem vários alunos matriculados.
Objetos em JavaScript
Objetos são definidos em JavaScript utilizando chaves ({ }
).
Os atributos de um objeto são declarados utilizando um par atributo:valor. Cada atributo é separado por vírgula.

Os atributos de um objeto são acessíveis utilizando o modificador . (ponto) da variável
console.log(a1.nome)
console.log(f1.diretor)
f1.data = "21.12.1990"
console.log(f1.data)
Objetos são referenciados! Cuidado ao tentar fazer cópia de um objeto! Use {...variavel} para fazer cópias ...
Objetos em JavaScript
Métodos nada mais são do que funções atreladas a um objeto.
let professorX = {
nome: "Zé lelé da Silva",
cpf:00000000-00,
siape: 23232,
titulo: "Doutor",
regime: "D.E.",
ingresso: 2011,
trabalhando: "Sim",
anosDeServico: function (){
return 2021 - professorX.ingresso
}
}
console.log(professorX.anosDeServico())
A palavra reservada this
em Objetos
O método anosDeServico
acessa um atributo do próprio objeto. Ao usar diretamente a variável professorX
no método podemos ter erros:
prof2 = {...professorX}
prof2.ingresso = 2015
console.log(prof2.anosDeServico())
A palavra reservada this
ao ser usada em um contexto refere-se sempre ao objeto que chamou o método naquele instante.
let professorX = {
//Atributos do professor ...
anosDeServico: function (){
return 2021 - this.ingresso
}
}
prof2 = {...professorX}
prof2.ingresso = 2015
console.log(prof2.anosDeServico())
console.log(professorX.anosDeServico())
Construtores e Classes
Todos são iguais, mas alguns são mais iguais que os outros...

Construtores
Anteriormente, definimos um objeto (professor) específico. Entretanto, alguns elementos do sistema possuem vários objetos, similares em sua estrutura, mas diferentes em seus dados. Um aluno, por exemplo:
let aluno1 = {
nome: "Lucy van Pelt",
cpf: "859.762.970-30",
RA: 1495741,
anoNascimento: 1995,
idade: function (){
return 2021 - this.anoNascimento
}
maiorIdade: function (){
this.idade() > 18
}
}
let aluno2 = {
nome: "Charlie Brown",
cpf: "187.127.690-02",
RA: 253984,
anoNascimento: 1994,
idade: function (){
return 2021 - this.anoNascimento
}
maiorIdade: function (){
this.idade() > 18
}
}

Construtores
Os construtores definem uma função de criação padrão para qualquer objeto que tenha as mesmas características
const aluno = function (nome, cpf, ra, ano){
this.nome = nome
this.cpf = cpf
this.ra = ra
this.anoNascimento = ano
this.idade = () => 2021 - this.anoNascimento
this.maiorIdade = () => this.idade() > 18
}
aluno1 = new aluno("Lucy van Pelt", "859.762.970-30", 1495741, 1995)
console.log(aluno1.nome)
console.log(aluno1.idade())
console.log(aluno1.maiorIdade())
aluno2 = new aluno("Charlie Brown", "071.773.210-04", 23425, 1994)
console.log(aluno2.nome)
console.log(aluno2.idade())
console.log(aluno2.maiorIdade())

Classes
Um conceito ainda mais poderoso é a ideia de classes. Classes englobam construtores de objetos:
class Aluno{
constructor(nome, cpf, ra, ano){
this.nome = nome
this.cpf = cpf
this.ra = ra
this.anoDeNascimento = ano
}
idade(){
return 2021 - this.anoDeNascimento
}
maiorIdade(){
return this.idade() > 18
}
}
let aluno1 = new Aluno("Linus van Pelt", "615.952.650-23", 25232, 2005)
let aluno2 = new Aluno("Ronald McDonald", "615.952.650-23", 14252, 2003)
console.log(aluno1.idade())
console.log(aluno2.idade(), aluno2.nome, aluno2.maiorIdade())
Classes vs Objetos

Classes são protótipos, nunca variáveis. Objetos são instâncias de classes.
Classes: Herança
class Pessoa{
constructor(nome, cpf, rg, ano){
this.nome = nome
this.cpf = cpf
this.rg = rg;
this.anoDeNascimento = ano
}
idade(){
return 2021 - this.anoDeNascimento
}
maiorIdade(){
return this.idade() > 18
}
}
class Aluno extends Pessoa{
constructor(nome, cpf, rg, ano, ra){
super(nome, cpf, rg, ano)
this.ra = ra
}
}
class Professor extends Pessoa{
constructor(nome, cpf, rg, ano, siape, titulo){
super(nome, cpf, rg, ano)
this.siape = siape
this.titulo = titulo
}
}
Classes podem herdar características em comum de outras classes:
rodrigo = new Professor("Rodrigo Duran", "012.570.380-52", 974482290, 1981, 23723, "Doutor")
console.log(rodrigo)
nome: 'Rodrigo Duran',
cpf: '012.570.380-52',
rg: 974482290,
anoDeNascimento: 1981,
siape: 23723,
titulo: 'Doutor'
}
let alunos = []
alu = new Aluno("Fulano DeTal", "589.829.980-71", 8324738, 2005, 2345 )
alunos.push(alu)
console.log(alu)
nome: 'Fulano DeTal',
cpf: '589.829.980-71',
rg: 8324738,
anoDeNascimento: 2005,
ra: 2345
}
alu = new Aluno("Ciclado DeTal", "849.445.330-04", 223211, 2007, 2344)
alunos.push(alu)
Classes: Polimorfismo
Mesmo método, diferentes resultados, dependendo do contexto.
class Animal {
constructor(nome, raca){
this.nome = nome
this.raca = raca
}
emitirSom(){
console.log("Animais podem fazer vários tipos de som ...")
}
}
class Gato extends Animal{
emitirSom(){
console.log("O gato mia ...")
}
}
class Cachorro extends Animal {
emitirSom(){
console.log("O cachorro late ...")
}
}
a1 = new Cachorro("Hippo", "Labrador")
a2 = new Gato("Godo", "Amarelo")
a1.emitirSom() //O cachorro late ...
a2.emitirSom() //O gato mia..