Docsity
Docsity

Prepare-se para as provas
Prepare-se para as provas

Estude fácil! Tem muito documento disponível na Docsity


Ganhe pontos para baixar
Ganhe pontos para baixar

Ganhe pontos ajudando outros esrudantes ou compre um plano Premium


Guias e Dicas
Guias e Dicas


Apostila Oficial- Ruby OO- Implementação, Notas de estudo de Informática

Programação Orientada a Objetos em Ruby

Tipologia: Notas de estudo

2015

Compartilhado em 02/02/2015

helvio-jeronimo-junior-3
helvio-jeronimo-junior-3 🇧🇷

3

(1)

1 documento

1 / 13

Toggle sidebar

Esta página não é visível na pré-visualização

Não perca as partes importantes!

bg1
Curso: Técnico de Informática para Web
Aluno:_____________________________________________________________
Disciplina: Programação Orientada à Objetos
Professor: Helvio Jeronimo Junior
Orientação à Objetos em Ruby: Implementação
1- Classes , Objetos e Métodos (Implementações simples)
Vamos agora ver como criar novos tipos de objetos. Como na maioria das outras
linguagens POO, um objeto Ruby é definido por uma classe. Como já estudamos,
a classe é como um "modelo" a partir do qual objetos individuais são construídos.
Esta é uma classe bem simples:
Class Livro
end
E assim é como eu criaria um objeto utilizável a partir dela:
um_livro= Livro.new
Esse trecho de código pode ser inserido:
1) ao fim da classe ou;
2) Em um arquivo a parte para teste de execução.
Neste caso, antes você deverá inserir na primeira linha deste arquivo uma
linha o seguinte trecho de código:
require 'Livro'
Isso significa que, para o código do arquivo ser executado ele requer a classe
Livro. Ou seja, precisa conhecer a estrutura da classe “Livro”
A princípio, neste momento não podemos fazer muita coisa com o meu objeto
“um_livro”- pela simples razão que eu não programei nada na minha classe Livro,
da qual o objeto foi criado.
Na verdade, se você criar uma classe vazia como a classe Livro, os objetos
criados a partir dela não são totalmente inúteis. Isso se deve pelo fato já explicado
anteriormente que todas as classes Ruby automaticamente herdam as
características da classe Object. Logo o objeto um_livro criado pode fazer uso dos
métodos de Object. Insira a linha de código apresentada a seguir , no fim da
classe livro ou no arquivo para teste de execução
pf3
pf4
pf5
pf8
pf9
pfa
pfd

Pré-visualização parcial do texto

Baixe Apostila Oficial- Ruby OO- Implementação e outras Notas de estudo em PDF para Informática, somente na Docsity!

Curso: Técnico de Informática para Web Aluno:_____________________________________________________________ Disciplina: Programação Orientada à Objetos Professor: Helvio Jeronimo Junior

Orientação à Objetos em Ruby: Implementação

1- Classes , Objetos e Métodos (Implementações simples)

Vamos agora ver como criar novos tipos de objetos. Como na maioria das outras linguagens POO, um objeto Ruby é definido por uma classe. Como já estudamos, a classe é como um "modelo" a partir do qual objetos individuais são construídos. Esta é uma classe bem simples:

Class Livro

end

E assim é como eu criaria um objeto utilizável a partir dela:

um_livro= Livro.new

Esse trecho de código pode ser inserido: 1) ao fim da classe ou; 2) Em um arquivo a parte para teste de execução. Neste caso, antes você deverá inserir na primeira linha deste arquivo uma linha o seguinte trecho de código:

require 'Livro '

Isso significa que, para o código do arquivo ser executado ele requer a classe Livro. Ou seja, precisa conhecer a estrutura da classe “Livro”

A princípio, neste momento não podemos fazer muita coisa com o meu objeto “um_livro”- pela simples razão que eu não programei nada na minha classe Livro, da qual o objeto foi criado.

Na verdade, se você criar uma classe vazia como a classe Livro, os objetos criados a partir dela não são totalmente inúteis. Isso se deve pelo fato já explicado anteriormente que todas as classes Ruby automaticamente herdam as características da classe Object. Logo o objeto um_livro criado pode fazer uso dos métodos de Object. Insira a linha de código apresentada a seguir , no fim da classe livro ou no arquivo para teste de execução

puts obj.class

O que aconteceu (saída)?

Para tornar a nossa classe um pouco mais útil, é preciso dar-lhe alguns métodos. Portanto, vamos adicionar a classe Livro o método chamado diga_algo.

class Livro

def diga_algo puts( "Olá Mundo" ) end end

Observe que um método é definido dentro da classe e usando a palavra def seguido do nome que lhe foi atribuído. O método acima quando executado irá exibir a mensagem “Olá Mundo”.

Para executar o método, este deve ser invocado da seguinte forma: nome_do_objeto.nome_do_metodo

Sendo assim, o método da classe Livro poderá ser chamado da seguinte forma:

um_livro = Livro.new ← Instanciando um objeto livro (criando) um_livro.diga_algo ← Invocando o método.

Reforçando, esse código pode ser inserido na classe “Livro” ou em um arquivo de teste.

Segundo as convenções de Ruby, nos nomes dos métodos deve-se usar letras minúsculas separando as palavras com um sublinhado ( _ ), porém nos nomes das classes é utilizado camel case , da mesma maneira que em Java, com maiúsculas separando duas ou mais palavras no nome da classe. Exemplos: MinhaClasse, MeuTeste,CarroPersonalizado.

Na criação da classe Livro , observa-se que não foram definidas propriedades para a mesma, que também são atribuídas aos objetos pertencentes a esta classe.

Essas propriedades do objeto são armazenadas no que chamamos variáveis de instância , que são quaisquer variáveis dentro do objeto cujo nome se inicia com @. Se fizermos referência para alguma que ainda não foi criada, ela será. Podemos inicializar várias dessas variáveis dentro do método initialize , que é o construtor do nosso objeto. A seguir são definidas algumas propriedades para a classe Livro. Essas propriedades são definidas no método i nitialize , ou seja, toda vez que um objeto da classe Livro for criado ele terá as propriedades definidas

Para testar:

um_livro = Livro.new ("12345","Paulo Coelho",49.0, 0.1) um_livro.preco_desconto ← chamando o método responsável por calcular o desconto.

Observações: Quando criamos uma classe, ganhamos automaticamente um método initialize default , para que o objeto possa ter suas informações inicializadas. Observe, que como queríamos passar dados para inicializar nosso objeto de uma maneira diferente, no caso passando o isbn, nome autor, preço, e percentual de desconto, tivemos que implementar nosso próprio método initialize em nossa classe Livro. Na verdade, sobrescrevemos o método initialize default, criando um método cujo nome deve ser initialize. O método initialize é um método especial do Ruby, in Nesse momento, o Ruby aloca espaço em memória e depois invoca o método initialize passando os parâmetros necessários para criar o objeto.

Vamos imaginar que existem alguns livros que não possuem o atributo isbn. Neste caso, a saída mais natural seria omitir o valor do isbn:

Tente executar:

ruby_on_rails= Livro.new (“Fábio Akita", 60.0, 0.2)

O que acontece?

Verifique que isso não funciona, pois para a linguagem Ruby, a aridade do método é importante, ou seja, devemos passar exatamente a quantidade de argumentos definido no método initialize. Em linguagens como Java, podemos definir um outro método initialize que recebe apenas o nome do autor e o número de páginas, recurso conhecido como sobrecarga:

class Livro def initialize(isbn, autor, preço, desconto) end def initialize (isbn, autor, preço, desconto) end end

No entanto, isso também não funcionará, pois o interpretador do Ruby considera apenas o último método definido na classe. Ruby não suporta sobrecarga. Para essa situação, a linguagem suporta o uso de argumentos com valores padrão:

class Livro

def initialize(isbn = "1"autor, preço, desconto) end end

Quando declaramos o argumento isbn = "1" , definimos que no momento da inicialização dos objetos do tipo Livro, podemos omitir o último argumento:

Teste:

ruby_on_rails= Livro.new (“Fábio Akita", 60.0, 0.2)

O valor do argumento isbn é “1”. Agora vamos inverter a ordem dos argumentos do método initialize , colocando o atributo isbn depois do atributo autor e vamos também imprimir os valores de cada um dos argumentos:

class Livro def initialize(autor, isbn = "1", preço, desconto) @isbn = isbn @autor = autor @preco = preço @desconto = desconto puts "Autor: #{@autor}, ISBN: #{@isbn}, Preco: #{@preço}, Perc. desconto: #{@desconto}" end end

Teste:

ruby_on_rails= Livro.new (“Fábio Akita", 60.0, 0.2)

E o resultado é: Autor: Fábio Akita, ISBN: 1, Preco: 60.0, Perc. Desconto: 0,2.

Veja que o Ruby é esperto e consegue atribuir o valor 6.0 ao atributo preço e não ao atributo isbn. Isso ocorre porque a linguagem Ruby possui três tipos de argumentos:  Obrigatórios;  Com valores padrão;  Opcionais.

Vimos dois deles até o momento: Obrigatório e com valores padrão. Veremos sobre os atributos opcionais mais adiante.

Verifique seus conhecimentos:

1- Para a classe Livro , altere o método que calcula o desconto, uma vez que só é possível obter um preço com desconto fornecido para o livro, caso o preço seja superior ou igual a R$ 50,00. Caso, o preço não atenda a condição, uma mensagem de aviso do não desconto deverá ser informada.

2- Acessores de Atributos e Visibilidade (Encapsulamento)

Vimos como criar as propriedades do nosso objeto através das variáveis de instância, mas como podemos acessá-las? Isso vai nos dar um erro:

class Livro def initialize(isbn, autor, preço, desconto) @isbn = isbn @autor = autor @preco = preço @desconto = desconto end end

um_livro = Livro.new ("12345","Paulo Coelho",49.0, 0.1) puts um_livro.isbn

Em Ruby, todas as variáveis de instância criadas são privadas, ou seja, não possuem acesso externo (fora da classe), nem para leitura, nem para escrita. Se quisermos acessá-las, vamos utilizar recursos da própria linguagem, que veremos a seguir.

Verifica-se que ao tentar executar classe Livro - definida no último exemplo, ocorrerá um erro ao tentar obter o isbn do livro em questão.

Já o trecho de código apresentado a seguir visa alterar o valor do atributo autor , ou seja, alterar o nome do autor do livro.

um_livro.autor= “Paulo Fernandes”

Ao tentar alterar o nome do autor do livro, é possível observar que um erro será gerado. Isso ocorre uma vez que, como mencionado anteriormente, essas variáveis são privadas do objeto, e não podem ser lidas e nem alteradas sem um método de acesso (leitura) e escrita.

Em outras linguagens, assim como no Ruby, os métodos responsáveis por essa tarefa são métodos: getters e setters. No entanto, a linguagem Ruby apresenta uma forma mais fácil para resolver esse problema, no qual usam-se: attr_reader, attr_writer e attr_acessor :

attr_reader → Define que fora da classe o atributo é somente de leitura; attr_writer → Define que o valor do atributo pode ser alterado fora da classe; attr_acessor → Define o atributo pode ser acessado e ter seu valor alterado fora da classe.

Exemplo: class Livro attr_reader :isbn attr_acessor :autor, :preço, :desconto def initialize(isbn, autor, preço, desconto) @isbn = isbn @autor = autor @preco = preço @desconto = desconto end end

um_livro = Livro.new ("12345","Paulo Coelho",49.0, 0.1) puts um_livro.autor um_livro.preço= 67.

No caso apresentado anteriormente, definiu-se que o atributo isbn é de leitura, que nos permitem a leitura de seus valores. Já os atributos autor, preço e desconto foram definidos como de leitura e escrita, que nos permitem que o valor contido nestes objetos possam ser lidos e alterados.

3- Visibilidade dos métodos

A visibilidade dos métodos é definida pelas palavras reservadas: public, private e protected. Normalmente, para definir a visibilidade dos métodos, usa-se a palavra reservada e na linha seguinte a implementação do método. Por convenção da linguagem, normalmente, os métodos definidos como private e protected são implementados ao final da classe/ arquivo. Por padrão, no Ruby todos os métodos definidos em uma classe são públicos.

4- Variáveis de Classe e Métodos de Classe

São variáveis que se encontram no contexto da classe e não das instâncias dos objetos da classe. Variáveis de classes tem o nome começado com @@ e devem ser inicializadas antes de serem usadas. Por exemplo: Suponha que se deseja saber qual a quantidade de livros cadastrados no sistema.

class Livro attr_reader :isbn attr_acessor :autor, :preço, :desconto @@qtd_livros = 0 def initialize(isbn, autor, preço, desconto) @isbn = isbn @autor = autor @preco = preço @desconto = desconto @@qtd_livros+= end

sugestão e o nome do usuário. Logo, para esse caso, sabe-se que este método será de instância, ou seja, para cada objeto livro. Um exemplo de implementação para este caso é:

class Livro attr_reader :isbn attr_acessor :autor, :preço, :desconto @@qtd_livros = 0a quantidade de livros esta sendo inicializado com o valor 0 def initialize(isbn, autor, preço, desconto) @isbn = isbn @autor = autor @preco = preço @desconto = desconto @@qtd_livros+=1indica que toda vez que um novo livro é criado, o qtd de livros existentes é atualizada end def comentário_livro(msg, leitor)método com os parâmetros na ordem em que serão passados puts “#{msg}. Esse comentário é de: #{comentário}” end def self.qtd_livrosindica que é um método de classe puts “A quantidade de livros cadastrados é #{@@qtd_livros}” end

end

um_livro = Livro.new ("12345","Paulo Coelho",49.0, 0.1) outro_livro = Livro.new ("1234","Markus Zusack",80.0, 0.2) Livro.qtd_livrosinvocando o método da classe um_livro.comentario_livro(“Muito bom”, “Helvio”)invocando o método e passando os parâmetros necessários outro_livro.comentario_livro(“Escrita cansativa”, “Helvio”)invocando o método e passando os parâmetros necessários

Teste seus conhecimentos: 1- Para a classe Livro , deseja que seja possível cadastrar sugestões de nomes de livros. Portanto: a) crie um método que seja responsável por registrar os nomes dos livros. Dicas: i) sabe que este será um método de classe. ii) muitos nomes de livros podem ser sugeridos, portanto a variável responsável por armazenar as sugestões deverá ser um array, que inicializará vazia. b) crie um método para mostrar todos os livros sugeridos.

2- Crie uma classe Conta Corrente no qual todos os objetos criados a partir desta classe deverão ser inicializados com os seguintes parâmetros: numero da agência, numero da conta, saldo atual e CPF do cliente. A classe deverá atender as seguintes exigências. a) Somente o valor do CPF do cliente poderá ser alterado fora da mesma;

b) Os demais atributos são privados, ou seja, só podem ser lidos fora da classe; c) Toda conta é criado com o valor de saldo igual a 0. d) A classe deverá implementar métodos no qual cada objeto do tipo conta terá seu valor de saldo atualizada após uma operação de depósito, saque e transferência. Ao realizar este tipo de operação os valores deverão ser passados por parâmetros. e) Deverá existir informar um método que retorna o total de contas existentes, isto é, o total de contas criadas. Dica: este será um método de classe que, consequentemente, trabalha com uma variável de classe.

5- Herança

Conforme apresentado anteriormente, a herança é um tipo de relacionamento entre as classes, no qual classes (subclasses) herdam propriedades e comportamento de outras classes (superclasse).

Vamos melhorar o contexto da classe que estava sendo utilizada anteriormente para nossos exemplos- a classe Livro. Vamos supor que está classe pertence a um contexto de uma loja de mídias. As mídias existentes nesta loja são CD’s, Livros e DVD’s. Portanto, sabemos que em maior nível de abstração teremos a classe Mídia. Esta classe tem os atributos título, preço, categoria e um desconto. Os atributos preço, categoria e desconto podem ser acessados e alterados. Alem disso, esta classe tem um método que é responsável por imprimir informações sobre o produto cadastrado. Portanto, teremos a estrutura dessa classe implementada da seguinte forma:

class Midia attr_accessor :preco :categoria, :desconto attr_reader :titulo

def initialize(titulo, preco, desconto, categoria) @titulo = titulo @preco = preco @desconto= desconto @categoria = categoria end

def informacoes puts “ O título da mídia é #{@titulo} e seu preço é #{@preco}, sendo que existe um desconto de #{@desconto}. Este produto pertence a seguinte categoria: #{@categoria}” end

def preco_desconto preco_desconto = @preco - (@preco * @desconto)

É possível observar que a implementação do método para exibir informações está diferente da lógica definida na classe Midia. Esse método foi reescrito – reescrita de método , um dos mecanismos possíveis quando se trabalha com a herança em orientação à objetos. Além disso, a classe Livro possuí um método denominado qtd_livros que não é definido na superclasse. Este método, de classe, foi implementado somente na subclasse.

Teste seus conhecimentos: 1- Crie uma classe Conta Bancária no qual:

a) A classe contém os seguintes atributos: nome do cliente, número da conta, saldo. Estes atributos devem ser inicializados toda vez que um objeto conta for criada. Toda conta criada tem valor de saldo = 0. Com exceção do saldo, todos os demais atributos são de acessíveis para leitura e escrita.

b) Esta classe deverá implementar métodos que sejam capazes de realizar operações de depósito, transferência e saque para cada conta. Em cada operação realizada o valor de saldo deve ser atualizado não podendo ficar negativo.

Obs: Após a implementação da classe, crie objetos a partir desta e teste os métodos implementados.

2- Crie duas classes, que são subclasses de Conta Bancária, denominadas Conta Poupança e Conta Especial, no qual:

a) A classe Conta Poupança possuí os atributos dia de rendimento e taxa de rendimento, que são somente de leitura. Esta classe deverá ter um método que seja responsável por atualizar o saldo de acordo com o dia e taxa informada. Este método deverá receber como parâmetro o dia de rendimento, caso este seja o dia de rendimento o valor do saldo deverá ser atualizado. Caso contrário, deverá existir uma mensagem que trate esta situação.

b) A classe Conta Especial deverá ter um atributo valor limite de (LIS). Nesta classe, os métodos que representam as possíveis transações (depósito, saque e transferência) deverão ser reescritos de forma que o saldo possa ficar negativo de acordo o valor de limite do LIS da conta.

Obs: Após a implementação das classes, crie objetos a partir desta e teste os métodos implementados.