
As classes são um dos pilares da OO e representam um
determinado objeto com suas características. Podemos
criar uma ou várias classes mas o comum é criar apenas
uma classe e que ela seja única dentro do sistema.
Uma classe determina o comportamento de determinado
objeto através de ações e características, ou seja
através de métodos e atributos.
Para criar classes em JS-ES5 utilizamos funções e
não classes.
Representamos objetos em JS-ES5 da seguinte forma:
function Objeto() {
}
ou
var Objeto = function() {
}
ou
var Objeto = {
}
Dentro das classes incluimos os atributos e métodos
abstraídos do objeto que vamos criar, por exemplo, para
uma pessoa temos como atributos
peso, altura, cor, etc e como métodos
andar, falar, nadar, etc.
Desse modo, quando instanciarmos a classe para criar um
novo objeto podemos acessar cada atributo ou ação dentro
do objeto.

Atributos são características que a classe terá. São
estruturas de dados que a classe irá representar.
Criamos os atributos na classe utilizando o operador
this. O operador this captura o escopo
da função onde ele está sendo utilizado e mantém este
escopo fechado na função.
Quando instanciamos a classe para um novo objeto esse
objeto terá os atributos da classe instaciada nele.
Os métodos seguem os mesmos conceitos dos atributos,
entretanto eles são ações/funções a ser executadas que
são criadas com um fim específico. Os métodos podem,
portanto ser executados a partir de um objeto
instanciado, mesmo que não haja nenhum valor definido
para seus atributos.
Importante ressaltar que caso seja criada uma função
dentro da classe sem utilizar o operador
this essa função não será englobada pelo escopo
da classe. Essa característica será melhor estudada em
modificadores de acesso.

Encapsulamento é a separação das características interna
e externa de um objeto. Esse mecanismo ajuda a proteger
os atributos uma vez que o acesso não é direto a ele e
sim a uma função que manipula os dados. Essas funções
são chamdas de getters e setters.
Para a construção dos métodos
getters/setters utilizamos a mesma sintaxe da
criação de métodos implementado uma função que fará a
atribuição de valor para o atributo no caso do
setter e uma função que irá retornar o valor do
atributo no caso do getter.
Quando os atributos são criados com o operador
this mesmo que criemos os
getters/setters eles ainda serão acessados fora
do objeto. Para realizarmos o encapsulamento devemos
declarar os atributos como variáveis de escopo local no
objeto com o operador var (ou let). A
partir disso os atributos só estarão disponíveis através
dos métodos getters/setters.

Métodos estáticos são métodos criados diretamente na
classe, sem que seja necessário instanciar um objeto.
Ele é criado fora da classe e pode ser acessado
diretamente pelo nome da classe. O mesmo pode ser feito
com atributos.
Não entendi para que serve criar um método ou
atributo estático.

O construtor é uma função que estabelece qual é o padrão
da instancia que deve ser criada.
Podemos atribuir parâmetros para que quando instanciamos
o objeto ele já receba os valores para os seus
atributos. Assim podemos alterar os valores de atributos
com o setter deste atributo, porém quando ele
for criado já podemos receber o resultado com o getter.

Modificadores de acesso são formas que nós conseguimos
ou não acessar métodos e atributos de uma classe. Para
ser implementado no JS-ES5 é necessário trabalharmos com
os escopos. Os modificadores de acesso são os
indicadores de classe public ou private.
No JS quando criamos atributos e métodos com o operador
this esses métodos e atributos ficam visíveis
para o resto da aplicação uma vez que tenha sido
instanciado em um objeto. Esses métodos e atributos são
considerados public.
Já atributos e métodos que são definidos com
var ou let o contexto passa a ser
exclusivo do método, podendo ser acessado apenas por
ele. O mesmo ocorre com métodos ou funções criados
apenas no escopo do método. Esses atributos e métodos
são considerados private e só podem ser
acessados por meio de outra atributo ou método que tenha
escopo global.
Essa operação tem como objetivo proteger os dados para
utilização apenas dentro do escopo da classe.

Resumindo, podemos acessar o prototype através dos valores __proto__ para os objetos instanciados ou pelo atributo prototype da classe. Quando criamos um método ou atributo diretamente no prototype de uma classe, diferente dos static method esses ficam acessíveis por qualquer objeto instanciado nessa classe. Desse modo podemos criar métodos fora da classe que se tornam acessíveis por qualquer objeto instanciado naquela classe.
Aula 11 - Herança via prototype
Herança é o mecanismo em que uma classe pode estender os
seus métodos e atributos para uma outra classe.
No JS-ES5 o processo para estender uma classe é bastante
complexo. Primeiramente precisamos passar os dados da
classe pai como parâmetros da classe filha. Em seguida
na classe filha devemos chamar os atributos e métodos
que vamos herdar da classe pai utilizando
Classe_pai.call(this, _attr1, _att2,..._attrn).
Feito isso vamos incluir o prototype da classe
pai na classe filha da seguinte forma:
Classe_filha.prototype =
Object.create(Classe_pai.prototype)

Polimorfismo consiste no princípio em que duas classes
que são pai e filho, ou que herdam da mesma super classe
podem invocar métodos com a mesma assinatura mas com
comportamentos distintos, especializando esses métodos.
Com o polimorfismo nós podemos mudar a lógica de um
método quando utilizamos classes herdadas utilizando o
mesmo nome(assinatura) do método herdado.