Métodos de Programação II (Mestrado Integrado em Engenharia de Comunicações) 1º Ano, 2º Semestre Classes Abstractas Métodos Programação II 1 Definições da SuperClasse • Muitas vezes torna-se difícil definir o interface que constitui a API da superclasse. • Há necessidade de certos métodos existirem na superclasse pelo simples facto de queremos todos objectos das suas subclasses a responderem ao protocolo definido pelo conjunto destes métodos. • Exemplo: Sabemos que as subclasses de FORMA tem de responder às interrogações aos métodos area() e perimetro(). Cada subclasse terá a sua implementação especifica. Mas o que escrever sobre estes métodas na superclasse FORMA ? Métodos Programação II 2 SuperClasses (2) • Na hierarquia anterior temos a certeza que todos os objectos de qualquer classe responde a area() e a perimetro(). • A certeza vem do facto de FORMA implementar estes métodos. Assim por herança ou por redefinição qualquer objecto desta hierarquia responde aos métodos em questão. • Uma dúvida surge: o que escrever na classe FORMA, por forma a que seja útil e reutilizável por todas as suas actuais e futuras subclasses. • Uma possível solução: escrever algo “dummy” que a primeira coisa a fazer pelo programador da subclasse é reescrever o método. •Exemplo: public double area() { return Double.MIN_VALUE; } public double perimetro() { return Double.MAX_VALUE; } • Uma solução: deixar as definições propositadamente incompletas. Métodos Programação II 3 Classes Abstractas • Classes Abstractas são exactamente todas as classes nas quais pelo menos um ou mesmo todos os métodos de instância não se encontram implementados, mas tão só declarados sintacticamente (daí serem designados como métodos abstractos ou virtuais). • No nosso exemplo, FORMA deve definir sintacticamente os métodos que as suas subclasses devem implementar. • Exemplo: public abstract class Forma { // definição dos métodos… public abstract double area(); public abstract double perimetro(); } • Para uma classe dever ser considerada abstracta basta não implementar um método. • Uma classe abstracta não tem instâncias. Métodos Programação II 4 Classes Abstractas (2) É sobretudo um tipo! • Uma classe abstracta é também (sobretudo) um tipo. • Assim a expressão: Forma f = new Triangulo(); continua a ser válida! • As subclasses de uma classe abstracta herdam o compromisso (obrigação) de implementar os métodos abstractos. Ou seja, a superclasse delega na subclasse a sua implementação. • Mas podemos ter uma hierarquia com várias classes abstractas. No entanto, pelo menos as classes folhas têm de implementar os métodos abstractos herdados. • Numa classe 100% abstracta, todas as suas subclasses respondem ao mesmo protocolo i.e. falam a mesma linguagem que foi herdada. • Uma classe 100% abstracta pode ser vista como uma especificação meramente sintáctica (ou seja, uma assinatura de um tipo de dados), Métodos Programação II 5 Classes Abstractas: resumo • Funções das Classes Abstractas: – Escrever especificações sintácticas para as quais múltiplas implementações são possíveis, de momento ou no futuro; – Normalizar a “linguagem” (API) a partir de certos pontos da hierarquia; – Introduzir flexibilidade e generalidade no código desenvolvido; – Tirar todo o partido do polimorfismo (via princípio da substituição); – Realizar classificações mais claras de subclasses. Métodos Programação II 6 Concretização do exemplo FORMA public abstract class Forma { // Classe abstracta public abstract double area(); public abstract double perimetro(); } TRIANGULO public class Triangulo extends Forma { /* altura tirada a meio da base */ // variáveis de instância private double base, altura; // construtores RECTANGULO CIRCULO public Triangulo() public class Rectangulo extends Forma { public class Circulo extends Forma { base = 0.0; altura = 0.0; } // variáveis de instância { // variáveis de instância public Triangulo(double b, double a) private double comp, larg; private double raio; { base = b; altura = a;} // construtores // construtores // métodos de instância public Rectangulo() { comp = 0.0; larg = 0.0; } public Circulo() { raio = 1.0; } public double area() public Rectangulo(double c, double l) public Circulo(double r) { return base*altura/2; } { comp = c; larg = l; } { raio = (r <= 0.0 ? 1.0 : r); } public double perimetro() // métodos de instância // métodos de instância { return base + (2*this.hipotenusa()); } public double area() { return comp*larg; } public double area() { return PI*raio*raio; } public double perimetro() { return 2*(comp+larg);} public double base() public double perimetro() { return 2*PI*raio; } public double largura() { return larg; } { return base; } public double raio() { return raio; } public double altura() public double comprimento() { return comp; } } { return altura; } } public double hipotenusa() { return sqrt(pow(base/2, 2.0) + pow(altura, 2.0)) ;} } Métodos Programação II 7 Métodos específicos das subclasses • Numa colecção de objectos FORMA como comunicar com as métodos específicos de triângulo? Forma f = new Rectangulo(4.0, 6.0); int b = f.comprimento(); Erro de compilação!!! • No entanto, podemos usar mecanismos de casting para comunicar com Triângulos: if(f instanceof Rectangulo) // testa tipo dinâmico int b = (Rectangulo f).comprimento(); else ..... Métodos Programação II 8 Classes abstractas e Variáveis de instância • Pode haver necessidade de definir na classe abstracta atributos comuns às suas subclasses. public abstract class ItemMulti Falta definir um constructor para esta classe abstracta, onde se inicializa as suas { variáveis de instância! // variáveis public ItemMulti(String tit, String dat, String com) private String titulo; { titulo = tit; data = dat; obs = com; } private String data; private String obs; // métodos para redefinição public abstract double duracao(); } Métodos Programação II 9 Cont() • Embora não seja possível criar instâncias de uma classe abstracta faz sentido estas terem construtores (para inicializar as suas variáveis de instância) public class Hi8 extends ItemMulti { // Variáveis de Instância private int minutos; private double ocupacao; private int gravacoes; // Construtores public Hi8(String titulo, String data, String obs, int min, double ocup, int gravc) { super(titulo, data, obs); // super ?? this.minutos = min; this.ocupacao = ocup; this.gravacoes = gravc; } ...... } Métodos Programação II 10 Classes Abstractas na API do Java • Muitas vezes funcionam como máximos denominadores comuns… (onde não é fácil ter uma relação de inclusão) • Por vezes reúnem as operações sobre uma abstracção (conjunto matemático). Neste caso específico a superclasse especifica as operações que devem existir sobre um conjunto de objectos. As subclasses implementam estas operações usando estruturas de dados específicas. Todas as classes são classes parametrizadas TreeSet<String> a; TreeSet<Ponto> b; Métodos Programação II 11 Método equals() e Herança • Na definição de igualdade, temos de ter em conta o que é herdado. Exemplo para a classe Ponto3D. public boolean equals(Object obj) { if ( this == obj ) return true; // é o próprio !! if ( obj == null ) return false; if ( this.getClass() != obj.getClass() ) return false; // Aqui temos a certeza que é um Ponto3D Ponto3D pp = (Ponto3D) obj; // casting obrigatório return super.getX() == pp.getX() && super.getY() == pp.getY() && this.z == pp.getZ(); } Métodos Programação II 12 Exercícios • Definir uma classe abstracta Forma. • Definir a seguinte hierarquia de classes: • Implementar os métodos apresentados. • Definir a classe FigGeo que guarda um conjunto de figuras geométricas. • Adicionar a classe Quadrado e Elipse (subclasse de Círculo) • Implementar um método que determina a figura com a maior área e qual o seu tipo e outro método para o maior perímetro. • Um método para contabilizar o número de figuras por tipo. Métodos Programação II 13 Exercícios (2) • Criar um banco que guarda as contas num ArrayList • Definir uma classe abstracta Conta. • Definir vários novos tipos de contas: conta à ordem, conta a prazo, conta jovem, conta ordenado e capital: – Prazo, tem uma taxa e um número de dias. Só há um debito que coincide com o final do prazo. – Jovem, tem taxa fixa de 1% TANB – Ordenado, dá um plafond de um valor pré definido. Isto é, permite estar com saldo devedor até ao montante estabelecido. – Conta Capital, que contém uma taxa de juro variável, indexada por períodos. A rentabilidade é calculada sobre estes períodos. O plafond desta conta é indexado ao capital investido. • Contar número de contas por tipo, inserir contas na classe Banco e calcular despesa em juros que o banco tem que pagar. Métodos Programação II 14