Baixe o app para aproveitar ainda mais
Prévia do material em texto
E-Book - Apostila 5-Reutilizando códigoe detegando tarefas (DL) E-Book - Apostila Esse arquivoé uma versão estática. Para melhor experiência, acesse esse conteúdo pela m ídia interativa. Reutiti cédigo lega ta E-Book - Apostila Chegamos na unidades de estudos em que falaremos sobre reutilizar códigose delegar tarefas. Antes de iniciar, leia com atençãoo textoa seguir. Reflexão Daniel atuou por muitos anos como engenheiro de software para sistemas de aluguel de veículose estava habituado com as particularidades do setor. Após alguns anos no mercado de trabalho, recebeua oportunidade de atuar em um projeto de jogo digital. Sua missão foi atuar na estruturação de um projeto parecido com o conhecido Pokémon, em queo jogo teria mais de 300 personagens controláveis. Daniel começoua refletir sobre como criar um sistema com reaproveitamentos de códigose estruturas que serviriam como base expansívele controle de tantos personagens. Assim como Daniel, ao longo de sua carreira você terá desafios dessa magnitude. Para superá-los, alguns conceitos como herançae composição são importantes. Vamos estudá- los? 2- 22 E-Book - Apostila Ao final deste conteúdo, você será capaz de: • Compreender aplicaçõese formas de utilização de herança de classes; • Implementar classes como relação tem-um (composição); • Diferenciaro uso de herançase interfaces; • Utilizar recursos de polimorfismo na estruturação de soluções computacionais. 3 - 22 E-Book - Apostila Um sistema computacional desenvolvido com uma linguagem de programação orientadaa objetos é, comoo nome doparadigma sugere, composto porobjetos que interagem por meio da troca de mensagens (chamadas de métodos). Como sabemos, objetos são construídosa partir de classese um dos primeiros passos na implementação de um sistema computacional desse tipoé identificar as classes de interessee a forma como elas se relacionam. Em geral, há dois tipos de relacionamentos entre classes. Eles são chamados de TEM-UM (doinglês HAS-A)e É-UM (doinglês IS-A). Nesta unidade de estudo, veremos como ambos ostipos de relacionamentos entre classes viabilizamo reuso de código, uma das principais vantagens da orientaçãoa objetos. Deixar de reutilizar códigoé conhecido como "reinventara roda". Veja como isso pode sermá ideia: FIGURA1 - Comparando AUTOR,D020 Além da reusabilidade de código, veremos comoo relacionamento É-UM torna viável um dos recursos mais poderosos da orientaçãoa objetos, chamado polimorfismo. Relacionamento É-um (herança) Considereo sistema acadêmico da sua instituição de ensino. Ele possui diversas características que retratamo "minimundo" que foi definido paraa sua elaboração. Professores ministram disciplinase lançam notase faltas. Estudantes cursam disciplinas que pertencema cursose são matriculados em turmas. Veja: FIGURA2 - Exemplo1 4 - 22 AUTOR, 2020 E-Book - Apostila Professores, cursos, alunos, disciplinas, turmas etc. são "coisas" do mundo real de interesse paraa implementação deste sistema.A implementação das classes que representam professorese alunos pode serfeita da seguinte forma: class Professor { private int matricula; private String nome; private String endereco; private int idade; class Aluno { private int ra; private String nome; private String endereco; private int idade; Você vê algum problema nesse código? As características de interesse para professorese alunos foram levantadase implementadas corretamente.O que pode haver de ruim? 5 - 22 class Professor { private int matricula; private String nome; private String endereco; private int idade; } class Aluno { private int ra; private String nome; private String endereco; private int idade; } E-Book - Apostila Emboraa implementação esteja correta, note que há repetição de código: as classes possuem atributos iguaise eles foram escritos duas vezes. Para enxergara razão pela qual issoé muito ruim, considerea seguinte nova necessidade: todas as pessoas do sistema devem terregistradoso seu sexo, RGe CPF. Além disso,o nome deve ser,a partir de agora, armazenado em duas variáveis: uma parao primeiro nomee outra parao sobrenome. Veja: class Professor { private int matricula; private String primeiroNome; private String sobrenome; private String endereco; private int idade; private String rg; private String cpf; private char sexo; class Aluno { private int ra; private String primeiroNome; private String sobrenome; private String endereco; private int idade; p rivate String rg; p rivate String cpf; p rivate char sexo; Percebeu como essa simples mudança nosrequisitos do sistema causou um tremendo pesadelo paraa manutenção do código? Acabamos de ilustrara "técnica" CTRL+C/CTRL+V de programação:o programador escreveu um trecho de código uma única veze o replica em diversas classes. Ocorre que se os requisitos mudarem novamente, eleterá de fazer alterações em múltiplas partes do projeto, tornandoa manutenção cada vez mais demoradae cara! Veja: FIGURA3 - 'Técnica' CTRL/C CTRL/V de programação 6-22 class Professor { private int matricula; private String primeiroNome; private String sobrenome; private String endereco; private int idade; private String rg; private String cpf; private char sexo; } class Aluno { private int ra; private String primeiroNome; private String sobrenome; private String endereco; private int idade; private String rg; private String cpf; private char sexo; } AUTOR, 2020 E-Book - Apostila Felizmente, nesta unidade estamos estudando uma técnica que permite evitar isso. Trata-se da herança, queé um nome bastante utilizado parao relacionamento É-UM entre classes. Seu usoé bastante simples. Para aplicá-la no cenário que descrevemos atéentão, basta: Identificar classes que têm características em comum. Identificar, no mundo real, uma 'coisa' que seja apropriada para abrigar tudo aquilo que identificamos em comum nopasso anterior. Escrever uma classe que abriga todas as características em comum. Remover todas essas características das classes existentes previamente. Fazer com que elas herdem da classe recém-criada. No cenário descrito, podemos dizer que professorese alunos têm diversas coisas em comum, pois ambos sãopessoas.O que eles têm em comum todas as pessoas têm. Assim, escrevemos uma classe para abrigar as características em comume fazemosa herança acontecer. Note que extendsé a palavra-chave utilizada na linguagem Java para representara herança. Veja: 7- 22 class Pessoa { E-Book - Apostila private String primeiroNome; private String sobrenome; private String endereco; private int idade; p rivate String rg; p rivate String cpf; p rivate char sexo; class Professor extends Pessoa{ private int matricula; class Aluno extends Pessoa { private int ra; Neste caso, ambas asclasses Professore Aluno têm todas as características definidas na classe Pessoa, já que ambas herdam dela. Note, contudo, que os atributos estão encapsulados. Eles somente podem seracessados por meio de métodos de acessoe modificadores, os famosos getters/setters. Emboraa herança seja um mecanismo sofisticado paraa reusabilidade de código,é recomendável que seu uso seja moderado. Em particular, ela somente deve seraplicada para casos que são condizentes com a realidade. Por exemplo, fazsentido dizer que Aluno É-UM Pessoa. Assim,a classe Aluno pode reutilizar código da classe Pessoa por meio da herança. Por outro lado, não faz sentido dizer que Veículo É-UM Motor. Assim, emboraa classe Veículo precise de detalhes da classe Motor para ser implementada, isso não deve serfeito por meio da herança. 8- 22 class Pessoa { private String primeiroNome; private String sobrenome; private String endereco; private int idade; private String rg; private String cpf; private char sexo; } class Professor extends Pessoa{ private int matricula; } class Aluno extends Pessoa { private int ra; } Estudo Guiado E-Book - Apostila Vamos entender melhoros conceitos básicos de herança? Leia as páginas de 279a 297. Clique no link e leiao livro DEITEL, P.; DE IT EL, H. J ava - Como Programar. 10.ed. São Pau lo: Pearson Education do Brasil, 2017. Relacionamento tem-um (composiçâo) Outro tipo de relacionamento entre classes chama-se "TEM-UM".O nome "composição" tambémé bastante comum para ele. Como decostume, seu usoe aplicações baseiam-se em observações no mundo real: observamos "coisas" que naturalmente têm um relacionamento desse tipoe fazemosa implementação por meio da especificação de variáveis de instância. Veja alguns exemplosa seguir. Usamosa expressão "TEM-UM" como um termo técnico mesmo. U m veículo TEM-UM motor. U ma pessoa TEM-UM emprego. 9- 22 https://plataforma.bvirtual.com.br/Leitor/Publicacao/1142/pdf/0 E-Book - Apostila Como mencionado,a implementação do relacionamento TEM-UMé feita por meio da especificação de variáveis de instância. Veja os exemplosa seguir: class Motor{ class Veiculo{ //Veiculo TEM-UM Motor private Motor motor; class Emprego( class Pessoa { //Pessoa TEM-UM Emprego private Emprego emprego; Em um exemplo mais elaborado, considere uma instituição de ensino que possui diversos professorese diversas disciplinas que precisam serministradas por eles. Uma atribuiçãoé uma "coisa" do mundo real que envolve um professore a disciplinaa que ele pode servinculado. Um professor pode estar associadoa diversas disciplinas. Uma disciplina, por sua vez, pode estar associadaa diversos professores. Temos, assim, uma lista de atribuições. Vejao exemploa seguir. class Professor { private String nome; private String titulacao; public Professor (String nome, String titulacao) { 10-22 class Motor{ } class Veiculo{ //Veiculo TEM-UM Motor private Motor motor; } class Emprego{ } class Pessoa { //Pessoa TEM-UM Emprego private Emprego emprego; } class Professor { private String nome; private String titulacao; public Professor (String nome, String titulacao) { this.nome = nome; E-Book - Apostila this.tituIacao = titulacao; class Disciplina { private String nome; private String descricao; public Disciplina (String nome, String descricao) { this.nome = nome; this.descricao = descricao; class Atribuicao { //Atribuição TEM-UM Professor private Professor professor; //Atribuição TEM-UM Disciplina private Disciplina disciplina; public Atribuicao (Professor professor, Disciplina disciplina) this.p rofessor = p rofessor; this.disciplina = disciplina; class Universidade { //Universidade TEM-UM lista de atribuições private List atribuicoes = new ArrayList <> (); public void adicionarAtribuicao (Atribuicao atribuicao) { this.atribuicoes.add(atribuicao); public class TesteAtribuicao { public static void main (String... args) { Universidade universidade = new Universidade(); Professor p1 = nem Professor ('José', 'Doutor'); Professor p2 = new Professor ( 'Maria' , 'Doutora' ) ; Disciplina dl = nem Disciplina ('Matemática', 'Matemática Elenentar' ) ; Disciplina d2 = nem Disciplina ('Compiladores', 'Construção de compiladores'); universidade.adicionarAtribuicao(nes Atribuicao universidade.adicionarAtribuicao(new Atribuicao universidade.adicionarAtribuicao(nes Atribuicao 11 - 22 ( p1, d 1) ) ; ( p2, d 1) ) ; ( p2, d2) ) ; this.nome = nome; this.titulacao = titulacao; } } class Disciplina { private String nome; private String descricao; public Disciplina (String nome, String descricao) { this.nome = nome; this.descricao = descricao; } } class Atribuicao { //Atribuição TEM-UM Professor private Professor professor; //Atribuição TEM-UM Disciplina private Disciplina disciplina; public Atribuicao (Professor professor, Disciplina disciplina) { this.professor = professor; this.disciplina = disciplina; } } class Universidade { //Universidade TEM-UM lista de atribuições private List atribuicoes = new ArrayList <> (); public void adicionarAtribuicao (Atribuicao atribuicao) { this.atribuicoes.add(atribuicao); } } public class TesteAtribuicao { public static void main (String... args) { Universidade universidade = new Universidade(); Professor p1 = new Professor ('José', 'Doutor'); Professor p2 = new Professor ('Maria', 'Doutora'); Disciplina d1 = new Disciplina ('Matemática', 'Matemática Elementar'); Disciplina d2 = new Disciplina ('Compiladores', 'Construção de compiladores'); universidade.adicionarAtribuicao(new Atribuicao (p1, d1)); universidade.adicionarAtribuicao(new Atribuicao (p2, d1)); universidade.adicionarAtribuicao(new Atribuicao (p2, d2)); } } E-Book - Apostila Saiba Mais Tantoa composição quandoa herança viabilizama reusabilidade de código. Em geral,a flexibilidade do sistema tendea sermaior quandoa reusabilidadeé feita por meio da composição. Além disso, muitas linguagens de programação possuem somente herança simples (comoé o caso da linguagem Java) e, por essa razão,a herança deve serreservada para quandoo relacionamento É-UM entre classes realmente fizer sentido no mundo real. Implementação de interfaces A interação entre classesé interessantee fundamental parao funcionamento de um sistema computacional. Contudo, desejamos que elaocorra de modo queasclasses envolvidas saibam poucos detalhes de implementação umas dasoutras. Considerea seguinte analogia com o mundo real. Como proprietário de um veículo, você deseja dirigi-lo. Para isso, entre outras coisas, você precisa acelerá-lo, evidentemente. Para fazê-lo, você deseja utilizar uma interface padronizada, comuma qualquer veículo. Você não deseja saber os detalhes internos do veículo, de sua mecânica, os detalhes do seu motor. Você deseja simplesmente acelerar.E pode fazer isso pisando no pedal do veículo. Eventualmente, no futuro, quando você trocar de veículo, você não deseja terde fazer um curso de mecânica para aprendera aceleraro seu novo veículo, só porqueo motor agoraé diferente. Você deseja utilizara mesma interface que usava no veículo anterior:o acelerador. Imagine as duas situações: Situação1 - Uma pessoa sentada no banco do motorista de um fusca. Dá para ver que seu pé está pisando no acelerador. Situação2 -A mesma pessoa sentada no banco do motorista de uma Ferrari. Também dá para ver que seu pé está pisando no acelerador. 12-22 E-Book - Apostila Voltando ao desenvolvimento de software, teríamos, neste exemplo, uma classe chamada Pessoae algumas classes para representar veículos diferentes. Dizemos que há um contrato entre Pessoae tudo aquilo que for um Veículo: Esse contrato estabelecea existência do método acelerar. Para acelerar seu veículo, uma pessoa somente chama esse método, sem saber dos detalhes de implementação da classe queo implementa. Estamos falando do recurso conhecido como interface. Uma interfaceé um contrato entre classes cujo principal objetivoé promovero baixo acoplamento para as suas interações. Vejao exemploa seguir: 13 - 22 interface Veicu{o{ public void acelerar(); E-Book - Apostila class Fusca implements Veiculo{ @0verride public void acelerar() { System.out.print{n('Fusquinha acelerandooo.... '); class Ferrari implements Veiculo{ @0verride public void acelerar() { System.out.print{n('Ferrraariiii aceleraaaaandooooooo.... '); class Pessoa { private Veiculo veiculo; pub{ic void dirigir (){ //dar partida //soltar o freio de mào veiculo. acelerar(); public void setVeiculo(Veiculo veiculo) { this.veiculo = veicu{o; public class Contrato { pub{ic static void main(String[] args) { Pessoa p = new Pessoa (); p.setVeiculo(nem Fusca()); p.dirigir(); p.setVeiculo(nem Ferrari()); p.dirigir(); 14 - 22 interface Veiculo{ public void acelerar(); } class Fusca implements Veiculo{ @Override public void acelerar() { System.out.println('Fusquinha acelerandooo....'); } } class Ferrari implements Veiculo{ @Override public void acelerar() { System.out.println('Ferrraariiii aceleraaaaandooooooo....'); } } class Pessoa { private Veiculoveiculo; public void dirigir () { //dar partida //soltar o freio de mão veiculo.acelerar(); } public void setVeiculo(Veiculo veiculo) { this.veiculo = veiculo; } } public class Contrato { public static void main(String[] args) { Pessoa p = new Pessoa (); p.setVeiculo(new Fusca()); p.dirigir(); p.setVeiculo(new Ferrari()); p.dirigir(); } } E-Book - Apostila Curiosidade Classes abstratas são um mecanismo muito parecido com interfaces. Elas servem para definir uma interface comuma diferentes classes. Ocorre que, eventualmente, pode serde interesse definir partes concretas (e não somente métodos sem implementação) que serão compartilhadas entre todas as subclasses. Neste casoo uso de classes abstratas pode ser conveniente. Polimorfismo -A sobrecarga de métodosé um tipo de polimorfismo, pois, do ponto de vista do código-cliente, um mesmo método pode serchamado deformas diferentes, embora saibamos que, na verdade, tratam-se de vários métodos com nome igual. Esse tipo de polimorfismo é, geralmente, chamado de polimorfismo estático. Estático no sentido de ser realizado pelo compilador. Generics 0 recurso conhecido como Generics do Java permite um tipo de polimorfismo, pois ele permite que uma classe (ou método) se comporte de forma diferente de acordo com um ou mais tipos de dados que sáo especificados em tempo de compilaçáo. Esse tipo de polimorfismoé conhecido como polimorfismo paramétrico. Sobrescrita de métodos A sobrescrita de métodosé um tipo de polimorfismo em que, em tempo de execução,a JVM decide qual método colocar em execução de acordo como tipo do objeto utilizado. Objetos diferentes recebema mesma mensagem (ouseja, um nome denome igualé chamado sobre eles) e, de acordo com seu tipo, apresentam comportamento diferente. Esse tipo de polimorfismoé conhecido como polimorfismo dinâmico. Dinâmico no sentido de ser realizado pela JVM, ou seja, em tempo de execução. Quando sefala somente de polimorfismo,é comum queseesteja referindo ao polimorfismo dinâmico. Esseé o assunto desta seção. 15-22 E-Book - Apostila A fim de ilustraro polimorfismo, precisamos de uma hierarquia de classes, como essa: public class Animal { public void fazerBarulho (){ System.out.println('Animal fazendo barulho'); public class Gato extends Animal{ public class Cachorro extends Animal{ Note que, devidoà herança, ambas asclasses Gatoe Cachorro têm acesso ao método "fazerBarulho". Vejao exemploa seguir: public class TesteSemVariaveisPolimorficas { public static void main(String[] args) { Gato gato = new Gato ( ); Cachorro cachorro = new Cachorro (); gato. fazerBaruaho(); cachor ro. faze rBaru1ho(); 16-22 public class Animal { public void fazerBarulho () { System.out.println('Animal fazendo barulho'); } } public class Gato extends Animal{ } public class Cachorro extends Animal{ } public class TesteSemVariaveisPolimorficas { public static void main(String[] args) { Gato gato = new Gato (); Cachorro cachorro = new Cachorro (); gato.fazerBarulho(); cachorro.fazerBarulho(); } } U ma variável polimórficaé uma variável de referência capaz de referenciar diferentes (mú ltiplos,d a ío seu nome) tipos de objetos. E-Book - Apostila Até então, nada de mais.O próximo passo para chegarmos ao ponto em queo polimorfismoé ilustrado,é entendero que são variáveis polimórficas. No exemploa seguir, as duas variáveis de referência utilizadas são polimórficas. Note que elas são capazes de fazer referênciaa qualquer subtipo de Animal. public class TesteComPolimorfismo { public static void main(String[] args) { Animal al = new Gato(); Animal a2 = new Cachorro(); al.fazerBarulho(); a2.fazerBarulho(); A seguir, precisamos entender que métodos herdados podem terseucomportamento personalizado pelas classes que os herdam. Neste exemplo,é de interesse que cada subtipo de Animal façaa implementação do método fazerBarulho de acordo com o tipo que representa. Gatose Cachorros miame latem, por exemplo. Vejaa nova definição delas: 17-22 public class TesteComPolimorfismo { public static void main(String[] args) { Animal a1 = new Gato(); Animal a2 = new Cachorro(); a1.fazerBarulho(); a2.fazerBarulho(); } } E-Book - Apostila public class Gato extends Animal{ public void fazerBarulho (){ System.out.println ('miau'); public class Cachorro extends Animal{ public void fazerBarulho (){ System.out.println ('au au'); Assim, podemos teruma coleção de animais na qual cabem animais de quaisquer tipos. Quando iterarmos sobre ela, podemos chamaro método fazerBarulho sem saber, de fato, qual método será chamado. Em tempo de execução, em função do tipo do objeto (e não da variável de referência)a JVM decide qual colocar em execução. Note que esse mecanismo substitui uma estrutura de seleção queo programador poderia terde manter. Vejao exemploa seguir: 18-22 public class Gato extends Animal{ public void fazerBarulho() { System.out.println('miau'); } } public class Cachorro extends Animal{ public void fazerBarulho() { System.out.println('au au'); } } E-Book - Apostila import java.utiI.ArrayList; import java.utiI.List; class Animal{ public void fazerBarulho (){ System.out.println('Animal fazendo barulho'); class Gato extends Animal{ public void fazerBarulho() { System.out.println('miau'); class Cachorro extends Animal( public void fazerBarulho() ( System.out.print{n('au au'); public class Polimorfismo { public static void main(StringI] args) { List animais = new ArrayLista>(); animais.add(new Gato()); animais.add(new Gato()); animais.add(new Cachorro()); for (Animal animal : animais) //polimorfismo dinâmico aqui //em tempo de execução, a JVM decide qual //método chamar em função do tipo do objeto animal.fazerBarulho(); 19-22 import java.util.ArrayList; import java.util.List; class Animal{ public void fazerBarulho () { System.out.println('Animal fazendo barulho'); } } class Gato extends Animal{ public void fazerBarulho() { System.out.println('miau'); } } class Cachorro extends Animal{ public void fazerBarulho() { System.out.println('au au'); } } public class Polimorfismo { public static void main(String[] args) { List animais = new ArrayList<>(); animais.add(new Gato()); animais.add(new Gato()); animais.add(new Cachorro()); for (Animal animal : animais) //polimorfismo dinâmico aqui //em tempo de execução, a JVM decide qual //método chamar em função do tipo do objeto animal.fazerBarulho(); } } E-Book - Apostila Diferenciar os momentos em queo vínculo de métodos aconteceé muito importantee tem impacto no desempenho do sistema computacional. Por exemplo,o polimorfismo estáticoé feito pelo compilador,o que quer dizer que quandoo programa estiver em execução, já serão conhecidos cada um dos métodos que devem serchamados em cada ponto do programa. Por outro lado,o polimorfismo dinâmico depende do tipo do objeto. Dado que eleé conhecido somente em tempo de execução, cabeà JVM fazero vínculo do métodoa serchamado,o que pode terimpacto no desempenho do sistema. Estudo Guiado O polimorfismo dinâmicoé realmente poderoso, nãoé mesmo? Quetalimplementar um sistema de folha de pagamento de uma empresa fazendo uso dele? Veja como daspáginas 305a 321. Cl1que no link e leiao livro DEITEL, P.; DEITEL, H.J ava - Como Programar. 10.ed. São Paulo: Pearson Education do Brasil, 2017. Reaproveitar códigose delegar tarefasé essencial no desenvolvimento de competências de um programador. Estudamos diversos conceitos para essa construção, dentre eles: 20-22 https://plataforma.bvirtual.com.br/Leitor/Publicacao/1142/pdf/0 E-Book - Apostila rati Feedba Agora que você está avançado no seu percurso dentro da unidade curricular digital, iremos resgatar a atividade do PRATIQUE. No fimda unidade 2, você encontroua atividade do PRATIQUE, fezo downloade realizouo que foi pedido, para que você consiga fazer uma autoavaliação,e entenda quala entrega esperadadessa atividade, apresentamosa vocêo feedback desta atividade. Neste documento você terá acessoà resposta esperada, entendendo assim,o percurso de conclusão da atividade. Leia atentamenteo arquivo, compare como documento que você preencheue corrija se for necessá rio. Vejao link com a sua ficha de feedback do pratique aqui: https://docs.google.com/presentation/d/1 kPZN3rS-zEAAWpAYz38u6OY8lPPabFdj/edit?usp=sharing&ouid=101311856548897159556&rtpof=true &sd=true 21-22 https://docs.google.com/presentation/d/1kPZN3rS-zEAAWpAYz38u6OY8lPPabFdj/edit?usp=sharing&ouid=101311856548897159556&rtpof=true&sd=true E-Book - Apostila Refe i ti ca DEITEL, P.; DEITEL, H. Java - Como Programar. 10.ed. São Paulo: Pearson Education do Brasil, 2017. 22 - 22
Compartilhar