Baixe o app para aproveitar ainda mais
Esta é uma pré-visualização de arquivo. Entre para ver o arquivo original
* Prof. Leonardo Cruz. leonardocruz@id.uff.br Departamento de Computação, UFF Programação Orientada a Objetos com Java Interface Introdução Quando criamos uma classe, “quase sempre” expomos alguns métodos a códigos externos. Expor significa torná-lo acessível (público) Considere os métodos públicos como um contrato, o que você se compromete a fazer para o mundo externo. É verdade que a classe ChefeDeDepartamento define um contrato Mas não todo o contrato.... Tudo que existir na classe funcionário fará parte do contrato Tudo que existir na classe Pessoa fará parte do contrato Um chefe é todas essas “coisas” Introdução Vamos imaginar que esse diagrama de classe foi utilizado na a construção de um sistema.... por exemplo, de feira de ciências E agora você quer aproveitar em um programa de Pet Shop Surgem problemas.... Não há um comportamento de animal doméstico (Pet)... Um objeto Pet precisaria de métodos como serAmigavel() e brincar() Então ... Precisamos incluir esses métodos.... Primeira opção Inserir os métodos de Pet em Animal Segunda opção Inserir os métodos de Pet em Animal, mas sem implementação, todos os métodos abstratos Terceira opção Inserir os métodos de Pet em Dog e Cat Parece que precisamos de duas classes Na verdade precisamos de .... Uma maneira de termos comportamentos de animal doméstico em classes Pet Uma maneira de garantir que todas as classes Pet tenham os mesmos métodos definidos (assinatura do métodos) Tirar proveito do polimorfismo Herança Múltipla Java fornece uma solução... Tipo especial de classe, que não tem implementação Uma interface define um protocolo (contrato) Classes podem implementar uma ou mais interfaces Uma interface é um contrato assinado por uma classe A interface define as responsabilidades da classe As responsabilidades são mapeadas em métodos A classe que implementa a interface implementa os métodos A interface contém somente assinatura de métodos e constantes Interfaces A definição de uma interface é similar a de uma classe Utilizamos a palavra reservada interface A palavra reservada deve ser seguida do nome da interface Uma interface pode herdar de outras interfaces (extends) A interface possui apenas métodos (todos) sem implementação (abstratos) e constantes Leonardo Murta Herança e Polimorfismo * public interface <nome da interface> { } No exemplo... public interface Pet { public abstract void serAmigavel() ; public abstract void brincar() ; } Na classe Dog... public class Dog extends Canine implements Pet { public void serAmigavel() {.......} public void brincar() {.......} . . . } Deve ser implementado Os outros métodos Herdados de Canine e sobrepostos A interface não interfere no mecanismo de herança. Interfaces - Características Uma interface não pode ser instanciada, da mesma forma que uma classe abstrata. Todos os métodos de uma interface são implicitamente abstract e public. Interfaces - Características Ao criarmos uma interface estamos criando um compromisso de que as classes que a implementarão, possuirão determinados métodos com uma assinatura pré-definida Uma classe herdeira pode herdar de apenas uma única classe (abstrata ou não) mas qualquer classe pode implementar várias interfaces simultaneamente. Interfaces - Características o corpo dos métodos de uma interface não pode ser declarado. atributos em uma interface, caso existam, são considerados static e final, devendo assim, ser inicializados em sua declaração. interfaces não podem ter construtores Interfaces - Características Interfaces podem ser úteis para implementar bibliotecas de constantes, já que atributos, caso existam em interfaces, são considerados static e final. Assim, qualquer classe que implemente uma interface com constantes terá acesso aos seus atributos. Exemplo 2 public interface Area { public double calcularArea(); } public class Circulo implements Area { private double raio; public Circulo(double raio) { this.raio = raio; } public double calcularArea() { return raio * raio * 3.14; } } public class Quadrado implements Area { private double lado; public Quadrado(double lado) {this.lado = lado; } public double calcularArea( ) { return lado*lado; } } Exemplo 3 interface MedalhaOlimpica { static final String OURO = “Ouro"; static final String PRATA= “Prata"; static final String BRONZE = "Bronze"; } public class AtletaOlimpico implements MedalhaOlimpica { private String medalha ; public void vencerEvento(){ medalha = OURO; } public interface ObjetoGeometrico { Ponto2D centro (); double calculaArea (); double calculaPerimetro (); } Exemplo 4 class Ponto2D { private double x,y; Ponto2D (double x, double y) { this.x = x; this.y = y; } public double getX(){ return this.x } public double getY(){ return this.y } public String toString () { return "(" + x + "," + y + ")“; } } class Circulo implements ObjetoGeometrico{ private Ponto2D centro; private double raio; Circulo (Ponto2D c, double r) { this.centro = c; this.raio = r; } public Ponto2D centro () { return this.centro; } public double calculaArea () { return Math.PI * this.raio * this.raio; } public double calculaPerimetro () { return 2.0 * Math.PI * this.raio; } public String toString () { return "Circulo: centro - " + centro + "/ raio - " + raio; } Exemplo 4 Implementação dos métodos da interface ObjetoGeometrico Math.PI é uma constante que esta na classe Math, e representa o valor de PI. public static final double PI = 3.14159265358979323846; class Retangulo implements ObjetoGeometrico{ private Ponto2D primeiroCanto, segundoCanto; Retangulo(Ponto2D pc, Ponto2D sc) { primeiroCanto = pc; segundoCanto = sc; } public Ponto2D centro() { double coordX = (primeiroCanto.getX() + segundoCanto.getX()) / 2.; double coordY = (primeiroCanto.getY() + segundoCanto.getY()) / 2.; return new Ponto2D(coordX, coordY); } public double calculaArea () { double ladoX = Math.abs(primeiroCanto.getX() - segundoCanto.getX()); double ladoY = Math.abs(primeiroCanto.getY() - segundoCanto.getY()); return ladoX * ladoY; } public double calculaPerimetro () { double ladoX = Math.abs(primeiroCanto.getX() - segundoCanto.getX()); double ladoY = Math.abs(primeiroCanto.getY() - segundoCanto.getY()); return 2 * ladoX + 2 * ladoY; } public String toString() {return "Retângulo com cantos " + primeiroCanto + " e " + segundoCanto; } Exemplo 4 public static void main(String[] argumentos) { // centrado na origem, raio 100 Circulo c1 = new Circulo(new Ponto2D(0, 0), 100); // centrado em (-1,-1), raio 1 Circulo c2 = new Circulo(new Ponto2D(-1, -1), 1); // um canto está em (-2,-2) e o outro canto em (2,2) Retangulo r1 = new Retangulo(new Ponto2D(-2, -2), new Ponto2D(2, 2)); // Vamos imprimir os dados completos de cada um destes objetos geométricos imprimeTodosOsDados(c1); imprimeTodosOsDados(c2); imprimeTodosOsDados(r1); } Exemplo 4 Parâmetros com Diferentes tipos de objetos imprimeTodosOsDados(c1); imprimeTodosOsDados(c2); imprimeTodosOsDados(r1); private static void imprimeTodosOsDados(ObjetoGeometrico og) Exemplo 4 É instância de círculo É instância de retângulo O método imprimeTodosOsDados imprime todos os dados de uma instância de uma classe que implemente a interface ObjetoGeometrico. private static void imprimeTodosOsDados(ObjetoGeometrico og) { // Primeiro, imprime os dados padrão do objeto - podemos fazer isto diretamente através da chamada implícita ao método toString System.out.println(og); // Podemos imprimir a sua área e perímetro com chamadas diretas aos métodos das classes System.out.println("Perímetro:" + og.calculaPerímetro()); System.out.println("Área:" + og.calculaÁrea()); } Exemplo 4 Verificando a classe... instanceof public static void main(String[] argumentos) { ObjetoGeometrico o1, o2, o3, o4; o1 = new Circulo(new Ponto2D(0, 0), 20); o2 = new Retangulo(new Ponto2D(-1, -1), new Ponto2D(1, 1)); o3 = new Circulo(new Ponto2D(-7, 3), 12.3); o4 = new Retangulo(new Ponto2D(0, 0), new Ponto2D(1, 1)); System.out.println("o1 é um Círculo ? " +(o1 instanceof Circulo)); //true System.out.println("o1 é um Retângulo ? " +(o1 instanceof Retangulo)); // false System.out.println("o1 é um ObjetoGeometrico ? " + (o1 instanceof ObjetoGeometrico)); // true System.out.println("o2 é um Círculo ? " + (o2 instanceof Circulo)); // false Exemplo 4 Observação - instanceof class Arvore{...} class Pinho extends Arvore{...} class Carvalho extends Arvore{...} public static void main( String[] args ) Arvore arvore = new Pinho(); . . . if( arvore instanceof Pinho ) System.out.println( "Pinho" ); if( arvore instanceof Carvalho ) System.out.println( “Carvalho" ); interface Escalavel { void amplia (double escala); // modifica os valores dos atributos do objeto para alterar a sua //posição (fazendo com que o objeto fique refletido nas suas // coordenadas horizontais void espelha() } Exemplo 5 Mais uma interface... class CirculoEscalavel implements ObjetoGeometrico, Escalavel { private Ponto2D centro; private double raio; Circulo (Ponto2D c, double r) { centro = c; raio = r; } public Ponto2D centro () { return centro; } public double calculaArea () { return Math.PI * raio * raio; } public double calculaPerimetro () { return 2.0 * Math.PI * raio; } public void amplia (double escala) { raio = raio * escala; } public void espelha(){ centro = new Ponto2D(- centro.getX(), centro.getY() } public String toString () { return "Circulo: centro - " + centro + "/ raio - " + raio; } } Exemplo 5 Implementação dos métodos da interface ObjetoGeometrico Implementação dos métodos da interface Escalavel Public static void main(String [] args) { CirculoEscalavel ce = new CirculoEscalavel (mew Ponto2D(10,10),30); System.out.println(ce instanceof CirculoEscalavel ); //true System.out.println(ce instanceof ObjetoGeometrico ); //true System.out.println(ce instanceof Escalavel ); //true } Exemplo 5 Pacotes Num sistema muito grande, seria inadequado a colocação de todas as classes num mesmo subdiretório. Como podemos organizar nossas classes e interfaces de forma mais lógica? Por exemplo, como separar classes que acessam uma base de dados das classes que preparam uma interface com o usuário? Pacotes Da mesma forma que agrupamos métodos e atributos relacionados a um mesmo tipo de objeto numa classe, faz sentido agruparmos classes relacionadas criando um pacote. Um pacote é implementado na forma de um subdiretório do sistema de arquivos empregado (Unix, Windows, etc) contendo estas classes com algum propósito semelhante. Pacotes Para criarmos um pacote colocamos as classes componentes num mesmo diretório e definimos a instrução package no início do arquivo, antes mesmo da definição da classe. Ex: package financeiro.banco.correntistas.Conta; Um pacote é implementado na forma de um subdiretório do sistema de arquivos empregado (Unix, Windows, etc). A classe que usar alguma outra classe presente num pacote deverá usar a instrução import. Ex: import financeiro.banco.correntistas.Conta; Pacotes // Arquivo ClienteConta.java package financeiro.banco.correntistas.Conta; public class ClienteConta { … } // Arquivo ClienteCC.java package financeiro.banco.correntistas.Conta; public class ClienteCC extends ClienteConta { … } // Arquivo ClientePoupanca.java package financeiro.banco.correntistas.Conta; public class ClientePoupanca extends ClienteConta { … } src\financeiro\banco\correntistas\Conta Pacotes Acesso a outros Pacotes Uma classe declarada num pacote pode acessar a classe de outro de 2 formas básicas: 1ª. Através do comando import // Arquivo ClienteConta.java package contabasica; public class ClienteConta { … } // Arquivo ClienteCC.java package contas; import contabasica.ClienteConta; public class ClienteCC extends ClienteConta { … } Acesso a outros Pacotes Uma classe declarada num pacote pode acessar a classe de outro de 2 formas básicas: 2ª. Colocando a referência completa à classe // Arquivo ClienteConta.java package contabasica; public class ClienteConta { … } // Arquivo ClienteCC.java package contas; public class ClienteCC extends contabasica.ClienteConta { … } Acesso a outros Pacotes Uma variante do import (import <nome-pacote>.*) permite que todas as classes deste pacote sejam importadas P. ex.: import contabasica.*; Visibilidade de Acesso public: acesso permitido a método localizado em qualquer classe protected: acesso permitido a método localizado na classe onde o recurso ocorre, nas especializações e no mesmo pacote private: acesso permitido a método localizado apenas na classe onde o recurso ocorre default (implícito): acesso permitido a método localizado no mesmo pacote do recurso Visibilidade de Acesso * * *
Compartilhar