Paradigmas de Programação Herança capacidade de uma classe (subclasse) herdar, adquirir atributos e funcionalidades de outra classe (superclasse), podendo juntar algumas especificidades e/ou alterar outras. Existe uma relação tipo “é-um...” entre objectos da subclasse e da superclasse Ex: carro_desportivo poderá ser uma subclasse de automóvel (carro_desportivo “é_um “ automóvel) 2009/2010 Tópicos das aulas Teórico Práticas Helena Leitão & Dulce Mota 1 Paradigmas de Programação Vantagens da Utilização de Herança •Estruturação •Reutilização de software •Economia de código •Economia de tempo em “debug” Nota : uma subclasse pode ser superclasse de outra 2009/2010 Tópicos das aulas Teórico Práticas Helena Leitão & Dulce Mota 2 Paradigmas de Programação Tipos de Herança •Herança simples – a subclasse só tem uma superclasse, isto é só herda de uma classe •Herança múltipla – a subclsse tem mais do que uma superclasse, herda de mais do que uma classe Nota : Java só admite herança simples 2009/2010 Tópicos das aulas Teórico Práticas Helena Leitão & Dulce Mota 3 Paradigmas de Programação Herança em Java extends – palavra chave que indica que uma classe é subclasse de outra protected – modificador de acesso que permite que componentes com este modificador sejam acessíveis na classe derivada e nas classes definidas no mesmo package 2009/2010 Tópicos das aulas Teórico Práticas Helena Leitão & Dulce Mota 4 Paradigmas de Programação Exemplo de herança em Java public classe Pai { ... ... } public class Filho extends Pai {... ... } public class Filha extends Pai {... ... } public class Neto extends Filho {... ...} Existe herança directa entre Filho e Pai Existe herança indirecta entre Neto e Pai 2009/2010 Tópicos das aulas Teórico Práticas Helena Leitão & Dulce Mota 5 Paradigmas de Programação Construtores na hierarquia de derivação em Java Quando se cria um objecto de uma subclasse o construtor chama imediatamente o construtor da superclasse (explicitamente através de super(...) ou implicitamente, por omissão). A execução do construtor implica a inicialização das v. de instância da superclasse que são parte do objecto da subclasse e só depois é que o construtor da subclasse inicializa as variáveis de instância da subclasse. Mesmo que o construtor não as inicialize explicitamente são inicializadas do seguinte modo: •Tipo numérico primitivo a 0 •Tipo boolean a false •Tipo referência a null 2009/2010 Tópicos das aulas Teórico Práticas Helena Leitão & Dulce Mota 6 Paradigmas de Programação Notas sobre herança em Java •Ao reescrever um método na subclasse o seu acesso não pode ser restringido, isto é, se é public na super classe não pode ser protected ou private na subclasse. •Um objecto da subclasse é um objecto da superclasse, isto é posso atribuir à classe Pai um objecto da classe Filho (o contrário é falso). •A classe Object é superclasse de todas as classes construídas em Java. •Para se aceder na subclasse a um método da superclasse, que está reescrito na subclasse, usa-se a palavra super.nome_do_método(...). 2009/2010 Tópicos das aulas Teórico Práticas Helena Leitão & Dulce Mota 7 Paradigmas de Programação Principais métodos da classe Object •boolean equals ( Object obj) deve ser reescrito em cada classe para comparar estado dos objectos e não verificar se referenciam o mesmo objecto. •Object clone( ) throws CloneNotSupportedException para classes que implementam Cloneable. •String toString( ) deve ser reescrito para todas as classes, devolve uma representação textual do objecto. •Class getClass( ) devolve um objecto que representa a classe de runtime do objecto this. •void finalize( ) throws Throwable executado antes do “garbage collector”, quando o objecto não possui referências associadas. 2009/2010 Tópicos das aulas Teórico Práticas Helena Leitão & Dulce Mota 8 Paradigmas de Programação Construtores na hierarquia de derivação (a superclasse) public class SuperClasse { protected int x; protected int z=20; { System.out.println("Bloco inicial da super"); } public SuperClasse() { System.out.println("Construtor da super"); setX(10); } public String toString() { return "x= "+x+" "+ "z= "+z+" "; }... ... 2009/2010 Tópicos das aulas Teórico Práticas Helena Leitão & Dulce Mota 9 Paradigmas de Programação Construtores na hierarquia de derivação (a subclasse) public class SubClasse extends SuperClasse{ private int y; { System.out.println("Bloco inicial da sub"); } public SubClasse() { super(); System.out.println("Construtor da sub"); y=11; } public String toString() { //reescrita do método toString() return super.toString() + "y= “ + y; } } 2009/2010 Tópicos das aulas Teórico Práticas Helena Leitão & Dulce Mota 10 Paradigmas de Programação Construtores na hierarquia de derivação ( teste) Saída: public class Teste { public static void main(String [] args){ SubClasse ep1=new SubClasse(); Construtor da super System.out.println(ep1); Bloco inicial da sub Construtor da sub } x= 10 } 2009/2010 Bloco inicial da super Tópicos das aulas Teórico Práticas Helena Leitão & Dulce Mota z= 20 y= 11 11 Paradigmas de Programação CLASSE ABSTRACTA É uma classe que não pode ser instanciada, geralmente é usada para derivar subclasses. Se tiver pelo menos um método abstracto (sem código) terá que ser forçosamente abstracta. É possível ser abstracta e ter todos os métodos com implementação Os métodos abstractos serão implementados nas subclasses, se o não forem, as subclasses serão também abstractas. Nenhum método abstracto de uma classe abstracta pode ser final, static ou private. 2009/2010 Tópicos das aulas Teórico Práticas Helena Leitão & Dulce Mota 12 Paradigmas de Programação CLASSE ABSTRACTA definição em Java Prefixa-se a definição da classe com a palavra abstract Exemplo: public abstract class Experiencia{ ... ... ... public abstract void metodoX( ) ; ... ... ... } 2009/2010 Tópicos das aulas Teórico Práticas Helena Leitão & Dulce Mota 13 Paradigmas de Programação Polimorfismo Significa existir em “muitas formas”. Traduz a capacidade de uma referência poder referenciar objectos de diversos tipos ( da mesma linha hierárquica) Exemplo: SuperClasse x=new SubClasse1( ); x=new SubClasse2( ); Nota: um tipo primitivo não pode armazenar informação de outro tipo, diz-se tipo monomórfico. 2009/2010 Tópicos das aulas Teórico Práticas Helena Leitão & Dulce Mota 14 Paradigmas de Programação Polimorfismo e Ligação Dinâmica Exemplo: class Forma { void desenhar( ...){ } } class Quadrado extends Forma{ void desenhar( ...){ ---- } } class Triangulo extends Forma{ void desenhar( ...){ ---- ---} } class Outra { void mostraDesenhos( Forma f) { f.desenhar(...); } } 2009/2010 Tópicos das aulas Teórico Práticas Helena Leitão & Dulce Mota 15 Paradigmas da Programação Polimorfismo e Ligação Dinâmica No exemplo anterior o método mostraDesenhos tem um parâmetro f do tipo Forma. Esta referência pode referenciar quer o tipo Quadrado quer o tipo Triângulo e na compilação não se sabe qual o método desenhar que vai ser executado, só na execução é que o sistema reconhece qual o tipo de objecto que f referencia e portanto só durante a execução é que sabe qual o método desenhar que vai ser executado. Esta capacidade chama-se Ligação Dinâmica (dynamic binding). 2009/2010 Tópicos das aulas Teórico Práticas Helena Leitão & Dulce Mota 16 Paradigmas de Programação Ligação Estática Na Ligação Estática no momento da compilação está definido qual o método a ser executado. Em linguagens como C, Pascal não existe ligação dinâmica, só existe ligação estática. 2009/2010 Tópicos das aulas Teórico Práticas Helena Leitão & Dulce Mota 17 Paradigmas de Programação Upcasting Característica da herança em que um objecto da subclasse pode ser usado como um objecto da superclasse. Esta conversão é sempre segura. Exemplo: Forma f1; Quadrado q1=new Quadrado(); f1=q1; // upcasting 2009/2010 Tópicos das aulas Teórico Práticas Helena Leitão & Dulce Mota 18 Paradigmas de Programação Downcasting Característica da herança em que uma referência (estática) da superclasse é atribuída a uma referência da subclasse . Esta conversão só é possível se a referência da superclasse tiver um tipo dinâmico do tipo da subclasse. Exemplo: Forma f1= new Quadrado(); //tipo estático de f1-- Forma //tipo dinâmico de f1-- Quadrado Quadrado q2; q2= (Quadrado) f1; // downcasting 2009/2010 Tópicos das aulas Teórico Práticas Helena Leitão & Dulce Mota 19 Paradigmas de Programação Tipo estático e dinâmico de uma referência Forma f1= new Quadrado(); tipo estático de f1-- Forma tipo dinâmico de f1-- Quadrado Na execução de métodos de instância são executados os métodos definidos na classe do tipo dinâmico (se existirem, senão procura na superclasse). Na execução de atributos de instância, de classe ou métodos de classe, são executados os referentes ao tipo estático do objecto. A compilação atende ao tipo estático das referências. 2009/2010 Tópicos das aulas Teórico Práticas Helena Leitão & Dulce Mota 20 Paradigmas de Programação Tipo estático e dinâmico de uma referência Forma f1= new Quadrado(); Na classe Forma: public void metodoX(){ Na classe Quadrado: public void metodoX(){ System.out.println(“Forma”); } f1.métodoX(); 2009/2010 System.out.println(“Quadrado”); } a saída desta instrução será Quadrado Tópicos das aulas Teórico Práticas Helena Leitão & Dulce Mota 21 Paradigmas de Programação Tipo estático e dinâmico de uma referência Forma f1= new Quadrado(); Na classe Forma: public static void metodoX(){ Na classe Quadrado: public static void metodoX(){ System.out.println(“Forma”); } f1.métodoX(); 2009/2010 System.out.println(“Quadrado”); } a saída desta instrução será Tópicos das aulas Teórico Práticas Helena Leitão & Dulce Mota Forma 22 Paradigmas de Programação Tipo estático e dinâmico de uma referência Forma f1= new Quadrado(); Na classe Forma: public class Forma{ Na classe Quadrado: public class Quadrado extends Forma{ public int lado=10; public int lado=55; ... ... ... ... ... ... System.out.println(f1.lado); a saída desta instrução será 10 2009/2010 Tópicos das aulas Teórico Práticas Helena Leitão & Dulce Mota 23 Paradigmas de Programação O operador instanceof Este operador permite verificar se o tipo dinâmico de um objecto é de uma dada classe ou não. Devolve falso caso o objecto não pertença à classe ou seja nulo. Exemplo: Forma f1= new Quadrado(); Quadrado q2=new Quadrado(); Quadrado q3=null; System.out.println( q2 instanceof Quadrado); System.out.println( q2 instanceof Forma); System.out.println( f1 instanceof Quadrado); System.out.println( q3 instanceof Quadrado); 2009/2010 Tópicos das aulas Teórico Práticas Helena Leitão & Dulce Mota Resultado: true true true false 24 Paradigmas de Programação Responda às seguintes questões: 1. Qual o tipo de relação semântica entre objectos em que existe composição. Exemplifique. 2. Considere as seguintes classes: public class Ponto { private int x,y; .... .... .... public class Circulo { private Ponto centro; private double raio; .... .... .... Descreva a instrução que permite criar um círculo de raio 10.5 e cujo centro se encontra nas coordenadas (2,3).Crie todas as funcionalidades para poder ser executada essa instrução. 2009/2010 Tópicos das aulas Teórico Práticas Helena Leitão & Dulce Mota 25 Paradigmas de Programação 3. Numa classe TesteCirculo como faria para que duas referências Circulo referissem o mesmo círculo. 4. Faça a verificação da alínea anterior. 5. Crie, na classe Círculo: a) um método booleano que permite verificar a igualdade entre círculos. Atenda a que dois círculos são iguais se tiverem o mesmo valor de raio e as coordenadas do centro forem as mesmas. b) um método que duplica um círculo. 2009/2010 Tópicos das aulas Teórico Práticas Helena Leitão & Dulce Mota 26 Paradigmas de Programação Responda às seguintes questões: 1. Qual o tipo de relação semântica entre objectos em que existe herança. Exemplifique. 2. Qual a palavra reservada em Java para indicar que uma classe é subclasse de outra. 3. Em Java qual a super classe de todas as classes. 4. Como classificaria o tipo de herança em Java (simples ou múltipla), justifique. 5. Distinga entre sobrecarga e reescrita de métodos numa linha hierárquica de classes 2009/2010 Tópicos das aulas Teórico Práticas Helena Leitão & Dulce Mota 27 Paradigmas de Programação 6. Qual a palavra chave para que um construtor da subclasse possa invocar um construtor da superclasse? 7. Indique os níveis de acesso dos membros da superclasse a que a subclasse acede. 8. Se uma subclasse herda todos os atributos e métodos da superclasse indique em que situação se obriga a utilizar super.membro_superclasse 9. Diga o que entende por polimorfismo. 10. O que é uma classe abstracta? 11. Para que uma subclasse, de uma superclasse abstracta, não seja também abstracta tem que ............... 2009/2010 Tópicos das aulas Teórico Práticas Helena Leitão & Dulce Mota 28 Paradigmas de Programação Considere a classe Animal e as subclasses Cao e Pato conforme se indica abaixo public class Animal { private String nome; private int n_patas; //Construtores public Animal(){... ... public Animal(String nome, int patas) {... //Selectores public String getNome() {... public int getN_patas() {... //Modificadores public void setNome(String nome) {... public void setN_patas(int n_patas) {... public String toString() {... } 2009/2010 Tópicos das aulas Teórico Práticas Helena Leitão & Dulce Mota 29 Paradigmas de Programação public class Cao extends Animal{ public class Pato extends Animal{ private String raca; private String cor; public Cao() {... ... public Cao(String nome,int patas,String raça) {... public Pato() {... ... public String getRaca() {... ... public String getCor() {... ... public void setRaca(String raca) {... ... public void setCor(String cor) {... ... public String toString() {... ... public String toString() {... ... public String falar() {... .... public String falar() {.... ... public Pato(String nome,int patas,String cor) {... } } Se no método main colocasse as seguintes instruções: teria erro de compilação. Justifique e indique como podia resolver este problema. 2009/2010 Animal c = new Cao(); System.out.println(c.falar() ); Tópicos das aulas Teórico Práticas Helena Leitão & Dulce Mota 30 Paradigmas de Programação Exercício 1. Construir a superclasse Animal com os atributos nome, nº de patas Os métodos a considerar são construtores, selectores, modificadores e toString(). 2. Desenvolver também as subclasses Cão e Pato. Cão, além dos atributos de Animal caracteriza-se pela raça e Pato pela cor. Estas subclasses devem implementar o método falar() que devolve um string representativo dos sons emitidos por cada animal (cao faz Au..Au e pato faz Quá..Quá) 3. A implementação das classes anteriores sugere que a classe Animal podia ser abstracta. Faça as alterações necessárias para considerar Animal como abstracta. 4. Crie a classe Zoo que é uma colecção de animais. Desenvolva métodos que liste como fala cada um dos animais do zoo, que conta o números de patos do zoo e liste as raças(sem repetição) dos cães do zoo. 2009/2010 Tópicos das aulas Teórico Práticas Helena Leitão & Dulce Mota 31 Paradigmas de Programação Exercício 1. Analise o diagrama de classes apresentado no próximo quadro. 2. Crie o código das classes envolvidas de modo que possa executar o seguinte método main(): package supermercado; import java.util.ArrayList; public class Teste { public static void main (String [] args) { Cliente c1 = new Cliente("Joao"); c1.compra(new ItemPrecoPeso("Bananas",1.5, 1)); c1.compra(new ItemPrecoPeso("Queijo",1.1, 10)); c1.compra( new ItemPrecoUnidades("Ananas",2, 2.5)); c1.compra( new ItemPrecoUnico("Livro", 10) ); ArrayList compras = c1.getCompras(); for (int i=0; i<compras.size(); ++i) System.out.println(compras.get(i)); } } 2009/2010 Tópicos das aulas Teórico Práticas Helena Leitão & Dulce Mota 32 Paradigmas de Programação Exemplo – consolidação da matéria 2009/2010 (exercício de exame) Tópicos das aulas Teórico Práticas Helena Leitão & Dulce Mota 33 Paradigmas de Programação package supermercado; import java.util.ArrayList; public class Cliente { private String nome; private ArrayList compras; public Cliente(String n) { nome = n; compras = new ArrayList(); } public void compra(ItemDeCompra c) { compras.add(c); } public ArrayList getCompras() { return compras; } } 2009/2010 Tópicos das aulas Teórico Práticas Helena Leitão & Dulce Mota 34 Paradigmas de Programação package supermercado; public abstract class ItemDeCompra { private static int proxNumId = 0; private int numId; private String nome; public ItemDeCompra() { numId = proxNumId++; } public ItemDeCompra( String n ) { this(); nome = n; } public String toString() { return "\t" + nome; } public abstract double custo(); } 2009/2010 Tópicos das aulas Teórico Práticas Helena Leitão & Dulce Mota 35 Paradigmas de Programação package supermercado; public class ItemPrecoUnidades extends ItemDeCompra { private int quantidade; private double precoUnitario; public ItemPrecoUnidades(String nome, int q, double pU){ super(nome); quantidade = q; precoUnitario = pU; } public double custo() { return quantidade * precoUnitario; } public String toString() { return super.toString() + "\t\t" + quantidade + " Unidades @ " + "\t" + precoUnitario + " Euros\t\t" + custo() + " Euros."; } } 2009/2010 Tópicos das aulas Teórico Práticas Helena Leitão & Dulce Mota 36 Paradigmas de Programação package supermercado; public class ItemPrecoPeso extends ItemDeCompra { private double peso; private double precoUnidadePeso; public ItemPrecoPeso(String nome, double p, double pUP) { super(nome); peso = p; precoUnidadePeso = pUP; } public double custo() { return peso * precoUnidadePeso; } public String toString() { return super.toString()+"\t\t"+peso+" Kg @ "+"\t" + precoUnidadePeso + " Euros\t\t" + custo() + " Euros."; } } 2009/2010 Tópicos das aulas Teórico Práticas Helena Leitão & Dulce Mota 37 Paradigmas de Programação package supermercado; public class ItemPrecoUnico extends ItemDeCompra { private double precoUnico; public ItemPrecoUnico(String nome, double pU) { super(nome); precoUnico = pU; } public double custo() { return precoUnico; } public String toString() { return super.toString() + "\t\t\t\t\t\t\t" + custo() + " Euros."; } } 2009/2010 Tópicos das aulas Teórico Práticas Helena Leitão & Dulce Mota 38