Baixe o app para aproveitar ainda mais
Prévia do material em texto
marcelo@ifpb.edu.br 3 MEU FILHO SE PARECE COMIGO! UM DIA TUDO DO MEU PAI VAI SER MEU! • Consiste em derivar novas classes a partir de outras já existentes – Reusabilidade de código – Parcial ou Total • Baseia-se no conceito de herança do mundo real – Características de uma geração (pai ou mãe) podem ser passadas aos mais novos (filhos) • É considerado um dos pilares da programação orientada a objetos 4 • Entre as classes que participam de um relacionamento onde há herança temos a seguinte situação: 5 subclasse superclasse filha (classe derivada) estende (é um(a)) pai (classe base) Notação UML • Quando uma classe estende outra, significa que ela é uma especialização de outra, ou seja um tipo específico 6 pessoa aluno é uma mamífero cachorro é um generalização especialização • A API Java está organizada de forma hierárquica: 7 Object Component Window Container • Podemos obter um conjunto de classes distintas a partir de uma única 8 animal mamífero ave réptil é um 9 animal mamífero ave réptil é um cobra lagarto é um Hierarquia de Classes ... • Quando uma classe estende outra, ela recebe os campos (variáveis e constantes) e as operações (métodos) • Deve-se respeitar as condições de acessibilidade de cada classe, assim como de seus campos e métodos 10 11 Caminhão carga total abrir compart. de carga fechar compart. de carga Automóvel número de pneus potência tipo de combustível andar freiar buzinar atributos: número de pneus, potência, tipo de combustível, carga total operações: andar, freiar, buzinar, abrir e fechar. 12 class Automovel { int numPneus,tipoComb; double pot; public void andar(){...}; public void freiar(){...}; public void buzinar() {...}; } class Caminhao extends Automovel { double cargatotal; public boolean abrir( ){ } public boolean fechar( ){ } } • A subclasse, quando necessário, deverá utilizar o construtor da superclasse para inicializar os atributos herdados • A chamada ao construtor da superclasse é feita através da palavra chave super 13 14 class Automovel { int numPneus,tipoComb; double pot; public Automovel(int numPneus,int tipoComb,double pot){ this.numPneus = numPneus; this.tipoComb = tipoComb; this.pot = pot } ... } 15 class Caminhao extends Automovel { double cargatotal; public Caminhao(int numPneus,int tipoComb,double pot,double tc){ super(numPneus,tipoComb,pot); this.cargatotal = cargaTotal; } } 16 Automóvel Caminhão new Caminhao(numPneus, tipoComb,pot,cargaTotal) super(numPneus,tipoComb,pot) this.cargaTotal = cargaTotal • Uma classe pode ter alguma operação que foi herdada do pai mas que tem uma implementação diferente: • Exemplo: um carro esporte pode ter uma forma de freiar diferente da forma típica de um automóvel. 17 18 automóvel numpneus pot tipocomb andar freiar buzinar caminhão cargatotal abrir fechar carro esporte freiar Reuso parcial Reuso total NOVO! • Se não queremos que uma classe seja estendida devemos utilizar o modificador final: 19 final class Automovel { int numpneus,tipocomb; double pot; public void andar( ) { ... }; public void freiar( ) { ... }; public void buzinar( ) { ... }; } • Se não queremos que um método seja sobreposto devemos utilizar o modificador final: 20 class Automovel { int numpneus,tipocomb; double pot; public final void andar() { ... }; public final void freiar() { ... }; public final void buzinar() { ... }; } • O acesso aos membros da classe pai depende do tipo de acesso concedido: – public: acessível a todas as classes, mesmo estando fora do pacote – private: inacessível a todas, exceto a própria classe – protected: acessível às subclasses e as classes do próprio pacote – default: acessível a todas as classes do mesmo pacote 21 22 Automóvel Caminhão public int numPneus private int tipoComb protected double pot public int numPneus protected double pot ? 23 PAI DESPREOCUPADO AINDA BEM QUE POSSO TER UM POUCO DE PRIVACIDADE.... Senha do Banco... Senha do CARTÃO DE CRÉDITO... 24 class Main { Triangulo triangulo = new Triangulo(); ... public void setTriangulo(Triangulo novoTriangulo){ Triangulo fig = novoTriangulo; } } setTriangulo :triangulo Apenas instancias da classe Triangulo podem entrar em setTriangulo 25 class Main { public static void main(String[] args){ Main m = new Main(); System.out.println(“escolha...”); int tipo = scan.nextInt(); switch(tipo){ case 1: m.setFigura(new Circulo()); break; case 2: m.setFigura(new Quadrado()); break; } } public void setFigura(Figura NovaFig){ Triangulo t = (Triangulo) novaFig; … } } setFigura :Quadrado :Circulo :Figura :Figura :Circulo :Quadrado ??? Instancias de qualquer classe que estenda Figura podem entrar em setFigura • Uma classe é abstrata quando pelo menos um de seus métodos não é implementado... • Nesse caso, a implementação fica por conta das subclasses • Isso é bastante comum quando um determinado comportamento é genérico demais... – Exemplo: o método andar da classe mamífero 27 28 public abstract class Mamifero { public abstract void andar( ); // Outros métodos } • A palavra chave abstract designa uma classe classe como sendo abstrata • O método sem implementação também deve ser designado com a palavra abstract 29 public abstract class Mamifero { public abstract void andar( ); // Outros métodos } • Uma classe abstrata não pode ser instanciada – tem que estendê-la e concretizá-la para poder realizar a instanciação • Uma classe abstrata pode ser estendida – a classe filha recebe todos os métodos passíveis de herança (inclusive os abstratos) e, portanto, passa a ser abstrata também 30 31 public abstract class cachorro extends Mamifero{ public abstract void andar( ); } mamífero cachorro extends Podemos ter cachorros que andam de forma diferente: reais (o seu cachorro!) e imaginários (o Snoopy anda em pé!) Por isso, deixaremos o método andar sem Implementação... andar() andar() • A idéia por trás do polimorfismo é que para uma mesma mensagem, objetos diferentes se comportem de forma diferente (poli = várias; morfo = forma) 32 andar() carro mamífero ??? • Não é preciso saber a priori quais os objetos especificamente iremos lidar, mas apenas genericamente – Via classes abstratas ou interfaces (falaremos disso mais tarde!) • A descoberta de quem vai responder à mensagem (chamada do método) ocorrerá em tempo de execução – Ligação Dinâmica (Dinamic Binding) 33 34 Figura Círculo Triângulo Quadrado é um area( ) area( ) area( ) area( ) Muito genérico! abstract class Figura { private String cor; public abstract double area( ); } • Classe Quadrado 35 class Quadrado extends Figura { private double b, alt; public Quadrado(double b, double alt){ this.b = b; this.alt = alt; } public double area(){return b*alt; } } • Classe Círculo 36 class Circulo extends Figura {static final double PI = 3.14; private double r; public Circulo (double r){ this.r = r; } public double area( ) { return r*r*PI; } } • Classe Triângulo 37 class Triangulo extends Figura { private double b; private double alt; public Triangulo(double b, double alt){ this.b = b; this.alt = alt; } public double area() { return b*alt/2; } } 38 public class Teste { public static void main(String[] args){ Figura[] fig = new Figura[3]; fig[0] = new Quadrado(1,2); fig[1] = new Circulo(2); fig[2] = new Triangulo(2,3); for(int i=0; i < 3; i++){ System.out.println(fig[i].area()); } } } • Uma interface é uma classe que possui todos os métodos abstratos e/ou declarações de constantes – Não têm variáveis – Não têm construtores – Não têm métodos implementados – Podem ter constantes 40 • “Programar para a Interface, não para a implementação” – Maior flexibilidade – Implementações mudam, conceitos ficam – Programar para o futuro e não para o presente 41 • Grau de Abstração 42 Classe Concreta atributos constantes métodos concretos Classe Abstrata atributos constantes métodos concretos métodos abstratos Interfaces constantes métodos abstratos • Uma interface é declarada da seguinte forma: 43 interface Operavel { static final int MAX = 10; public int soma(int a, int b); public int subtrai(int a, int b); public int multiplica(int a, int b); public int divide(int a, int b); } Método(s) abstratos(s) Constante(s) • Uma interface não deve ser instanciada, ela deve ser implementada: 44 public class calculadora implements Operavel{ public int soma(int a,int b){return a+b;} public int subtrai(int a,int b){return a-b;} public int mult(int a,int b){return a*b;} public int divide(int a, int b) {return a/b;} } • Podemos implementar mais de uma interface 45 Calculadora Operavel Representavel *-avel implements 46 class calculadora implements Operavel,Representavel{ // métodos de Operavel public int soma(int a, int b){return a + b;} public int subtrai(int a, int b){return a - b;} public int multiplica(int a, int b){return a*b;} public int divide(int a, int b){return a / b;} // método de Representavel public void exibeNaTela(int valor){ System.out.println(“O valor é ” + valor); } } • Um dos problemas da orientação a objetos é lidar com a necessidade de estender mais de uma classe ao mesmo tempo: 47 ? ? soma( ) A soma( ) B C ? • A solução em Java é implementar métodos de uma interface e estender métodos de outra 48 Calculadora Representável Verificadora implements implements extends Interfaces Classe Operável • Permite estender uma classe sem fazer herança 49 class calculadora extends Verificadora implements Operavel,Representavel { // métodos de Operavel public int soma(int a, int b){return a+b;} public int subtrai(int a, int b){return a-b;} public int multiplica(int a, int b){return a*b;} public int divide(int a, int b){return a/b;} // método de Representavel public void exibeNaTela(int valor){ System.out.println(“O valor é ” + valor); } } • Se todos os métodos da Interface não forem implementados, a classe será abstrata 50 Calculadora Operavel public int soma(int a, int b){ return a + b; } CalculadoraCientifica implements extends public abstratct int subtrai(int a, int b){ return a – b; } Interface Classe Abstrata Classe Concreta public abstratct int soma(int a, int b); public abstract int subtrai(int a, int b); public abstract int subtrai(int a, int b); 51 interface Operavel{ public int soma(int a, int b); public int subtrai(int a, int b); public int mult(int a, int b){return a*b;} public int div(int a, int b){return a/b;} } abstract class Calculadora implements Operavel{ public int soma(int a, int b){ return a + b; } } 52 class CalcCient extends Calculadora { public int subtrai(int a, int b){ return a-b; } public int multiplica(int a,int b){ return a*b; } public int divide(int a, int b){ return a/b; } } • A linguagem Java contém inúmeras interfaces em sua API: – java.util.Observer – java.lang.Cloneable – java.io.Serializable – Java.util.zip.Checksum 53 • Semelhante ao Polimorfismo com Classes Abstratas: – Os elementos aptos a executar uma determinada operação polimórfica deve implementar a Interface que define o Polimorfismo 54 55 public interface Comparavel { public boolean comparaCom(Object o); } 56 public class Livro implements Comparavel { private double preço; public Livro(double preço){ this.preço = preço; } public void setPreço(double novoPreço){ preço = novoPreço; } public double getPreço(){ return preço; } public boolean comparaCom(Object o){ if (o instanceof Livro){ Livro l = (Livro) o; if (this.getPreco() > l.getPreco()) return true; } return false; } } 57 public class Teste { public static void main(String[] args){ Teste meuTeste = new Teste(); Comparavel[] arrayComp = new Comparavel[3]; arrayComp[0] = new Livro(50.00); arrayComp[1] = new Livro(3000.00); arrayComp[2] = new Livro(0.80); System.out.println(“Antes...”); for(int i=0; i < 3; i++){ System.out.println(arrayComp[i].getPreço()); } meuTeste.ordenar(arrayComp); 58 System.out.println(“Depois...”); for(int i=0; i < 3; i++){ System.out.println(arrayComp[i].toString()); } } // main // Continua no próximo slide. 59 public void ordenar(Comparavel[ ] c){ int tam = c.length; Comparavel aux; for(int i=0; i < tam - 1; i++){ for(int j=1; j < tam; j++){ if(c[i].comparaCom(c[j])){ aux = c[j]; c[j] = c[i]; c[i] = aux; } } } } // fim de ordenar } // fim da classe • Upcast – Uma superclasse ou entidade genérica (classe abstrata ou interface) pode receber sempre uma subclasse ou entidade específica (classe implementadora) 60 Figura minhaFigura = new Triangulo(...); teste.insere(new Triangulo(2,3)); public void insere(Figura f) { /* código */ } 61 Caminhão peso total de carga abrir compart. de carga () fechar compart. de carga () Automóvel número de pneus potência tipoCombustível andar () freiar () buzinar () Automovel auto = new Caminhao(...); auto auto.andar() auto.freiar() auto.buzinar() OK! auto.abrir() auto.fechar() NÃO! • Downcast – Uma superclasse ou entidade genérica (classe abstrata ou interface) deve ser convertida explicitamente para o tipo da subclasse ou entidade específica (classe implementadora) 62 public boolean comparaCom(Object o){ Livro l = (Livro) o; if (this.getAno() < l.getAno()) return true; return false; } • Downcast – Se a referência em “o” não for um Livro teremos um problema! 63 Object Automóvel número de pneus potência tipoCombustível andar () freiar () buzinar () Livro título autor número de páginas mudarPagina () pesquisar (plv) ClassCastException Ok!!! • Downcast – Antes dese usar uma referência de uma entidade genérica é importante se testar sua origem: 64 if(o instanceof Livro) Object Livro o Object Automovel o 65 Superclasse / Interface (Figura) Subclasse / Classe Concreta (Circulo) Subclasse / Classe Concreta (Circulo) upcasting downcasting if(aluno1.comparaCom(aluno2)) { ... } ... public boolean comparaCom(Object o) { ... } Aluno aux = (Aluno) o; • Vamos projetar um jogo no qual será possível, de acordo com determinadas condições, mudar o braço de um robô. • Cada braço tem uma funcionalidade diferente... • A mudança deve ser feita de forma transparente 66 67 Robô Braço com Broca Braço com Tesoura ? ? 68 public class Robo{ private Cabeça c; private Perna p; private Tronco t; private Braço b; public Robo(Cabeça c, Perna p, Tronco t, Braço b){ this.c = c; this.p = p; this.t = t; this.b = b; } // Outros métodos... } 69 public class Robo{ // atributos ... public Robo(Cabeça c, Perna p, Tronco t, BraçoComTesoura bct){ /* corpo */ } } public class Robo{ // atributos ... public Robo(Cabeça c, Perna p, Tronco t, BraçoComBroca bcb){ /* corpo */ } } OU 70 <<interface>> Braço BraçoComGarra BraçoComBroca BraçoComArma implements atacar() atacar( ) atacar( ) atacar( ) 71 public interface Braço{ public void atacar(); } public class BraçoComGarra implements Braço { /* Corpo da Classe */ } public class BraçoComBroca implements Braço { /* Corpo da Classe */ } public class BraçoComArma implements Braço { /* Corpo da Classe */ } 72 public class Robo{ private Cabeça c; private Perna p; private Tronco t; private Braço b; public Robo(Cabeça c, Perna p, Tronco t, Braço b){ /* código */ } ... } 73 public class Robo{ private Cabeça c; private Perna p; private Tronco t; private Braço b; public Robo(Cabeça c, Perna p, Tronco t, Braço b){ /* código */ } ... } Qual é o tipo do braço do robô? O que mudou nessa classe? 74 public class RobotGame{ public static void main(String[] args){ Braço b1 = new BraçoComGarra(); Braço b2 = new BraçoComBroca(); Braço b3 = new BraçoComArma(); /* Criação de c1 e t1 omitida */ Robo r1 = new Robo(c1,t1,b1); Robo r2 = new Robo(c1,t1,b2); Robo r3 = new Robo(c1,t1,b3); /* Restante do Código */ r1.setBraco(b2); } Mesmo construtor, Diferentes Robôs • O tipo de braço do robô pode ser conhecido em Compile Time (estaticamente) ou Run Time (Dinamicamente) – A classe Robo é projetada sem levar em consideração o tipo de braço que será usado (o mesmo poderia ser feito para as demais partes) 75 76 • O Polimorfismo libera a classe cliente do tipo específico de comportamento que ela deve usar Braço abre() <<Interface>> Robô BraçoComBroca abre( ) BraçoComArma abre( ) 77 • Existem mecanismos bastante eficientes para o desenvolvimento de software flexível e reutilizável: Padrões de Projeto: 23 estratégias para se abordar o desenvolvimento de software de forma madura 78 Escreva um programa em Java que implemente um Sistema de Controle de Folha de Pagamento Simplificado de uma empresa, composta de diversos funcionários, os quais podem ser horistas ou comissionados. Todos os funcionários, independente de categoria, devem ter os atributos “nome”, “matrícula” e “salário”. Os horistas têm como atributo o “número de horas trabalhadas” (o valor de uma hora trabalhada é 30 reais) e os comissionados o “salário base” e o “total de suas vendas” durante o mês multiplicado por um “fator de comissão” (cujo valor é 2%). Um comissionado vende até três produtos diferentes. Um produto tem um “nome”, um “código” e um “preço” e existem dois tipos: “perecível” ou “não perecível” (o funcionário comissionado tanto vende produtos perecíveis como não perecíveis) . Um produto perecível tem uma “data de validade” e um não perecível tem um “prazo de garantia”. (I) O sistema deve ser capaz de cadastrar funcionários e produtos e informar o estado atual do funcionário que recebe o maior salário na empresa. 79 Funcionário nome matricula salário Horista Comissionado nome matricula salário quantHoras nome matricula salário salarioBase totalVendas 80 Funcionário nome matricula salário Horista Comissionado nome matricula salário quantHoras nome matricula salário salarioBase totalVendas 81 Funcionário nome matricula salário Horista Comissionado QuantHoras salarioBase totalVendas 82 Funcionário nome matricula salário Horista Comissionado QuantHoras salarioBase totalVendas Main main() arrayFunc 83 Produto nome preço código Perecível NãoPerecível dataVal: Date prazo: Date Main main() arrayFunc 84 Produto nome preço código Perecível NãoPerecível dataVal: Date prazo: Date Horista Comissionado QuantHoras salarioBase totalVendas Main main() arrayProd arrayFunc Funcionário nome matricula salário vende 3 10 10 tem tem • Requisitos Funcionais – O sistema deve ser capaz de cadastrar funcionários e produtos – O sistema deve ser capaz de informar o estado atual do funcionário com o maior salário 85
Compartilhar