Conteúdo principal
Curso: Programação > Unidade 1
Lição 16: Design Orientado a ObjetoRevisão: Modelo Orientado a Objetos
Esta é uma revisão do que abordamos nesse tutorial sobre o modelo orientado a objetos.
Quando nós criamos programas, frequentemente descobrimos que queremos criar muitos objetos os quais todos compartilham propriedades parecidas - como muitos gatos, que têm a cor do pelo ou o tamanho levemente diferentes, ou muitos botões, com diferentes rótulos e posições. Nós queremos poder dizer "isto é o que geralmente um gato é" e então dizer "vamos criar esse gato específico e esse outro gato, e eles serão parecidos em algumas formas e diferentes em outras formas também." Nesse caso, nós queremos usar um modelo orientado a objetos para definir os tipos de objetos e criar novas instâncias de tais objetos.
Para definir um tipo de objeto em JavaScript, nós primeiro temos que definir uma "função construtora". Essa é a função que nós iremos usar sempre que quisermos criar uma nova instância desse tipo de objeto. Aqui está uma função construtora para o tipo de objeto
Book
:var Book = function(title, author, numPages) {
this.title = title;
this.author = author;
this.numPages = numPages;
this.currentPage = 0;
};
A função recebe argumentos para os aspectos que serão diferentes para cada livro - o título, autor e número de páginas. Ela então atribui as propriedades iniciais do objeto baseada nesses argumentos, usando a palavra-chave
this
. Quando usamos this
em um objeto, estamos nos referindo à atual instância de um objeto, referindo-se a ele mesmo. Nós precisamos guardar as propriedades em this
para garantir que possamos nos lembrar delas futuramente.Para criar uma instância de um objeto
Book
, nós declaramos a nova variável para armazená-lo, então usamos a palavra-chave new
, seguida pela função construtora, e passamos os argumentos de entrada que o construtor espera:var book = new Book("Robot Dreams", "Isaac Asimov", 320);
Podemos então acessar qualquer propriedade que armazenamos no objeto usando a notação ponto:
println("I loved reading " + book.title); // I loved reading Robot Dreams
println(book.author + " is my fav author"); // "Isaac Asimov" is my fav author
Vamos examinar isso por um minuto, e mostrar o que teria acontecido se não definíssemos nossa função construtora corretamente:
var Book = function(title, author, numPages) {
};
var book = new Book("Little Brother", "Cory Doctorow", 380);
println("I loved reading " + book.title); // I loved reading undefined
println(book.author + " is my fav author"); // undefined is my favorite author
Se passarmos os argumentos para a função construtora, mas não os guardarmos explicitamente na
this
, então não poderemos acessá-los depois! O objeto terá se esquecido deles há muito tempo.Quando definimos tipos de objeto, muitas vezes queremos associar não só propriedades como também comportamentos neles - equivalente a todos nossos objetos do tipo cat serem capazes dos comportamentos meow() e eat(). Portanto precisamos ser capazes de atribuir funções para as nossas definições de tipos de objetos, e nós podemos fazer isso definindo-os no que é chamado de object prototype - objeto protótipo:
Book.prototype.readItAll = function() {
this.currentPage = this.numPages;
println("You read " + this.numPages + " pages!");
};
É similar a como definiríamos uma função normalmente, exceto que nós deixamos o protótipo
Book
pendurado em vez de simplesmente defini-lo globalmente. Essa é a maneira que o JavaScript sabe que é uma função que pode ser chamada em qualquer objeto Book
, e que essa função deveria ter acesso ao this
chamado dentro do objeto book.Podemos chamar a função (a qual chamamos de um método, já que ela está atribuída para um objeto), da seguinte forma:
var book = new Book("Animal Farm", "George Orwell", 112);
book.readItAll(); // You read 112 pages!
Lembre-se, o objetivo do design orientado a objeto é facilitar para nós a criação de múltiplos objetos relacionados (instâncias de objetos). Vamos ver isso no código:
var pirate = new Book("Pirate Cinema", "Cory Doctorow", 384);
var giver = new Book("The Giver", "Lois Lowry", 179);
var tuck = new Book("Tuck Everlasting", "Natalie Babbit", 144);
pirate.readItAll(); // You read 384 pages!
giver.readItAll(); // You read 179 pages!
tuck.readItAll(); // You read 144 pages!
Este código nos mostra três livros similares - todos têm os mesmos tipos de propriedades e comportamentos, mas são diferentes. Legal!
Agora, se você pensar sobre o mundo real, gatos e cães são diferentes tipos de objetos, então você provavelmente iria criar diferentes tipos de objetos para eles se você estivesse programando um
Gato
e um Cão
. Um gato iria miar()
, um cachorro iria latir()
. Mas eles também são similares, tanto o gato como o cão iria comer()
, ambos teriam uma idade
, um nascimento
e uma morte
. Ambos são mamíferos, e isso significa que eles compartilham uma grande quantidade de coisas em comum, mesmo sendo animais diferentes.Nesse caso, nós queremos usar a ideia de herança de objeto. Um tipo de objeto pode herdar propriedades e comportamentos de um objeto pai, mas também tem suas próprias coisas únicas referentes a ele mesmo. Todos os
Gatos
s e Cão
s podem herdar de Mamífero
, a fim de que eles não tenham que inventar comer()
do zero. Como faríamos isso em JavaScript?Voltemos ao nosso exemplo do livro, e digamos que
Book
é o tipo de objeto "pai", e nós queremos criar dois tipos de objetos que herdam dele - Paperback
(livro impresso) e EBook
(livro eletrônico).Um livro impresso é igual a um livro, mas tem uma diferença principal, pelo menos em nosso programa: ele tem uma imagem na capa. Portanto, nosso construtor precisa receber quatro argumentos para receber essa informação extra:
var PaperBack = function(title, author, numPages, cover) {
// ...
}
Agora, não queremos ter de refazer todo o trabalho que já fizemos no construtor
Book
para recordarmos aqueles três primeiros argumentos - queremos tirar vantagem do fato que o código para isso poderia ser o mesmo. Podemos, na realidade, chamar o construtor do Book
a partir construtor do PaperBack
e passar os argumentos:var PaperBack = function(title, author, numPages, cover) {
Book.call(this, title, author, numPages);
// ...
};
Entretanto, ainda precisamos armazenar a propriedade
cover
no objeto, então precisamos de mais uma linha para cuidar disso:var PaperBack = function(title, author, numPages, cover) {
Book.call(this, title, author, numPages);
this.cover = cover;
};
Agora, temos um construtor para nosso
PaperBack
, o que o ajuda a compartilhar as mesmas propriedades como Book
, mas também queremos que nosso PaperBack
herde seus métodos. Aqui está como fazemos isso, dizendo ao programa que o protótipo PaperBack
deve ser baseado no protótipo Book
:PaperBack.prototype = Object.create(Book.prototype);
Também podemos anexar um comportamento específico para o livro impresso, como poder queimá-lo, e podemos fazer isso definindo funções no protótipo, depois da linha acima:
PaperBack.prototype.burn = function() {
println("Omg, you burnt all " + this.numPages + " pages");
this.numPages = 0;
};
Agora podemos criar um novo livro impresso, lê-lo e queimá-lo!
var calvin = new PaperBack("The Essential Calvin & Hobbes", "Bill Watterson", 256, "http://ecx.images-amazon.com/images/I/61M41hxr0zL.jpg");
calvin.readItAll(); // Você lê 256 páginas!
calvin.burn(); // Meu Deus, você queimou todas as 256 páginas!
(Bem, não vamos queimá-lo de verdade, porque esse é um livro muito bom, mas, talvez fizéssemos isso se estivéssemos presos em um deserto glacial e desesperados por calor e prestes a morrer.)
Agora, você viu como podemos usar os princípios do modelo orientado a objetos em JavaScript para criar dados mais complexos para seus programas e modelar melhor os mundos criados com programação.
Quer participar da conversa?
- var calvin = new PaperBack("The Essential Calvin & Hobbes", "Bill Watterson", 256, "http://ecx.images-amazon.com/images/I/61M41hxr0zL.jpg");
Pela Khan Academy posso adicionar imagens em JavaScript como no código acima? Ou foi somente como exemplo?(18 votos) - eu posso declarar um
this.propriedade
como um array ou objeto, além de valor ou string?(3 votos)