UTFPR – DAELN - Disciplina de Fundamentos de Programação II ( IF62C ). 1 Prof. Robinson Vida Noronha e Danillo Belmonte Tema: Implementação de Classe e Auto-Relacionamentos em Java ---------------------------------------------------------------------------------------------------------------------------------------------- Implementação de Classe e Auto-Relacionamento em Java 1) Introdução Um modelo de Diagrama de Classes representa a estrutura definida para o armazenamento das informações dos elementos ou classes que irão trabalhar em conjunto para solucionar um problema ou desafio. Sendo esse diagrama um modelo conceitual, existe a necessidade de verificar a validade e completude desse modelo. Uma das formas de se fazer isso é por meio de implementação, ou geração de códigos em uma linguagem de programação Orientada a Objetos e realizações de testes de seu uso. Neste material, será analisado um modelo de uma classe que possui um relacionamento com ela mesmo. Quando isso ocorre, diz-se que há um AutoRelacionamento. Como objeto de estudo, definine-se uma classe que representa o conceito Disciplina. Considera-se, neste exemplo, que uma Disciplina possa possuir ou não como pré-requisitos outras instâncias da Disciplina. Ou seja, ela se relaciona com ela mesmo por meio do conceito “pré-requisito”. Por exemplo, na Figura 1 a seguir, a disciplina EL65E possui como pré-requisito as disciplinas EL64E, EL64F e EL64G. A disciplina EL64E, por sua vez, possui como pré-requisito a disciplina FI64A. Como essa estrutura poderia ser representada em um Modelo Orientado a Objetos? Para responder a essa questão, este documento está divido em 5 Seções. Na Segunda Seção, apresenta-se o cartão CRC da classe Disciplina. Na Seção 3, a partir do cartão CRC, o modelo UML da classe é definido e apresentado. Nesse instante, destacase que novas responsabilidades que não foram definidas no cartão CRC foram criadas com a finalidade de orientar o programador de computador e também facilitar ou permitir o (re)uso da classe. A Seção 4 apresenta a implementação da classe Disciplina. Encerrando este documento, na Seção 5 um exercício é deixado para o aluno resolver. De maneira similar ao apresentado anteriormente, o programador de computador deve ter a liberdade de definir ou personalizar a implementação. Ou seja, o programador UTFPR – DAELN - Disciplina de Fundamentos de Programação II ( IF62C ). 2 Prof. Robinson Vida Noronha e Danillo Belmonte Tema: Implementação de Classe e Auto-Relacionamentos em Java ---------------------------------------------------------------------------------------------------------------------------------------------- de computador implementa além dos métodos e atributos definidos no Diagrama de Classes UML, novos métodos e atributos que ele/ela achar necessário. Figura 1 - Grade parcial do Curso de Engenharia Industrial Elétrica da UTFPR, campus Curitiba adaptada para o exemplo investigado. 2) Representação Classe Disciplina O Cartão CRC apresentado na Figura 2, define os atributos ou “conhecimentos” que um elemento da classe Disciplina deve possuir. Figura 2 - CRC da Classe Disciplina UTFPR – DAELN - Disciplina de Fundamentos de Programação II ( IF62C ). 3 Prof. Robinson Vida Noronha e Danillo Belmonte Tema: Implementação de Classe e Auto-Relacionamentos em Java ---------------------------------------------------------------------------------------------------------------------------------------------- O cartão CRC representado na Figura 2 possui na área de Colaboradores, uma própria instância da classe Disciplina. O Auto-Relacionamento ocorre quando é definido como colaborador para uma classe, um exemplar da própria classe. Nesse caso, no canto à direita do cartão CRC existe uma referência à própria classe do cartão, a classe Disciplina. Isso acontece pois uma disciplina pode possuir nenhum, um ou vários prérequisitos e esse pré-requisito é uma outra instância da classe Disciplina. 3) Diagrama UML da Classe Disciplina A Figura 3, a seguir, apresenta o Diagrama de Classe da Classe Disciplina definida no cartão CRC ilustrado na Figura 2. Alguns detalhes e considerações utilizadas nessa representação merecem destaque, a saber: • No diagrama UML, cada responsabilidade indicada no CRC, pode ser um atributo ou um método. • As responsabilidades Codigo, Nome, Quantidade de Aulas Teóricas, Quantidade de Aulas Práticas e Quantidade de Aulas a Distância definidas no cartão CRC da Figura 2 foram representadas no diagrama da Figura 3. Os Anexos 6a), 6b), 6c) e 6d) ilustram a associação entre as responsabilidades do cartão CRC e o Diagrama de Classe. • Cada atributo foi definido com o modificador de acesso private ou privado. Isso é apenas uma recomendação: “atributos devem ser definidos com acesso private ou protected”. Essa representação é indicada pelo sinal “-” que precede o atributo. • Para cada atributo, métodos de acesso “geters” e “seters” de visibilidade pública foram definidos. Por exemplo, os métodos públicos “+setNome(v: String) : void” e “+getNome() : String” estão associados ao atributo Nome. • A responsabilidade “pre-requisito”, por sua vez não foi representada de maneira explícita no diagrama. De acordo com o diagrama, esse auto-relacionamento possui a multiplicidade “0..*”. Essa multiplicidade significa que a quantidade de prérequisitos pode variar de instância de classe para instância de classe. O Anexo 6e) ilustra a associação entre a representação do Auto-Relacionamento do Diagrama UML e o cartão CRC. • Cada linguagem de programação fornece ao programador um conjunto de opções para representar o Auto-Relacionamento. Por exemplo, na linguagem C++, poder-seia representar, por exemplo, com listas, vetores ou arrays esse conjunto de UTFPR – DAELN - Disciplina de Fundamentos de Programação II ( IF62C ). 4 Prof. Robinson Vida Noronha e Danillo Belmonte Tema: Implementação de Classe e Auto-Relacionamentos em Java ---------------------------------------------------------------------------------------------------------------------------------------------- elementos. Por outro lado, na linguagem Java, outras opções também estão disponíveis. Para deixar o programador livre para definir qual será a forma de implementação desse grupo de elementos, optou-se apenas por definir um método de inclusão e outro de remoção de pré-requisito. Os métodos são “addPreRequesitoNecessario(Disciplina)” e “removePreRequisitoNecessario (Disciplina)”. • As duas últimas responsabilidades definidas no cartão CRC “lista de quem sou prérequisito” e “lista pré-requisitos necessários” foram definidas como dois métodos no diagrama de classes. Esses métodos são: listaPreRequisitosNecessarios() e listaDeQuemSouPreRequisito( ). • Três outros métodos foram definidos no diagrama de classes e que não foram previstos no cartão CRC. Esses métodos são: i) “print( )”, ii) “equals(Disciplina)” e iii) “clone( )”. O método “print( )” imprime as informações consideradas importantes do conceito Disciplina. Por sua vez, o método “equals(Disciplina)”, verifica se duas instâncias da classe disciplina podem ser consideradas iguais. O método “clone( )” fornece uma cópia da instância. • Dois construtores também foram definidos. Um deles, não recebe argumento algum e o outro, recebe o código da disciplina e o seu respectivo nome. • O Auto-Relacionamento denominado por “preRequisito” é representado por uma linha que inicia e termina na própria classe. A multiplicidade desse relacionamento é “0..*”. Essa multiplicidade informa que uma determinada instância da classe Disciplina pode possuir nenhum, um pré-requisito ou vários. UTFPR – DAELN - Disciplina de Fundamentos de Programação II ( IF62C ). 5 Prof. Robinson Vida Noronha e Danillo Belmonte Tema: Implementação de Classe e Auto-Relacionamentos em Java ---------------------------------------------------------------------------------------------------------------------------------------------- Figura 3 - UML - Diagrama de Classe da Classe Disciplina 4.Implementação em Java A definição da assinatura da classe é apresentada no arquivo Disciplina.h a seguir. Algumas decisões realizadas necessitam ser exclarecidas, a saber: • os atributos Nome e Codigo da Figura 3 foram definidos como elementos String. • o Auto-Relacionamento é representado por elementos Vector ou ArrayList. Nesse exemplo definiu-se as duas opções para armazenar as disciplinas que são prerequisitos e também de quais disciplinas a classe é pre-requisito. • Alguns métodos que não foram definidos no Diagrama de Classes da Figura 3 foram definidos durante a programação. Esses métodos são: • java.util.Vector getPreRequisitos(); > definida com a finalidade de mostrar como um método pode ter uma instância da classe vector de retorno. UTFPR – DAELN - Disciplina de Fundamentos de Programação II ( IF62C ). 6 Prof. Robinson Vida Noronha e Danillo Belmonte Tema: Implementação de Classe e Auto-Relacionamentos em Java ---------------------------------------------------------------------------------------------------------------------------------------------- • boolean tenhoPreRequisitoNecessario(Disciplina v); > definido apenas como método auxiliar para os outros métodos. Por não ter sido definido no Diagrama de Classes, poderia ter sua visibilidade privada. • boolean souPreRequisito(Disciplina v); > definido apenas como método auxiliar para os outros métodos. Por não ter sido definido no Diagrama de Classes, poderia ter sua visibilidade privada. 4.1 Arquivo Disciplina.java package autorelacionamento; /** * * @author robinsonnoronha */ import java.util.Vector; public class Disciplina { private! ! String Codigo; private! ! String Nome; private! ! int QuantidadeAulasTeoricas; private! ! int QuantidadeDeAulasPraticas; private ! int QuantidadeDeAulasDistancia; private ! Vector preRequisitoNecessarios = new Vector( ); private ! java.util.ArrayList<Disciplina> deQuemSoupreRequisito = new java.util.ArrayList<Disciplina>(); public ! Disciplina(String v_codigo, String v_nome) { this();// chamada para o contrutor sem parâmetros. ! ! ! ! ! ! setNome(v_nome); setCodigo(v_codigo); } public { Disciplina() QuantidadeAulasTeoricas=0; QuantidadeDeAulasDistancia=0; QuantidadeDeAulasPraticas=0; } UTFPR – DAELN - Disciplina de Fundamentos de Programação II ( IF62C ). 7 Prof. Robinson Vida Noronha e Danillo Belmonte Tema: Implementação de Classe e Auto-Relacionamentos em Java ---------------------------------------------------------------------------------------------------------------------------------------------public void setQuantidadeAulasTeoricas(int v) { if (v>=0) QuantidadeAulasTeoricas = v;} public void setQuantidadeAulasPraticas(int v) { if (v>=0 ) QuantidadeDeAulasPraticas = v;} public void setQuantidadeAulasDistancia(int v) { if (v>=0 ) QuantidadeDeAulasDistancia = v;} public int getQuantidadeAulasTeoricas(){return QuantidadeAulasTeoricas;} public int getQuantidadeAulasPraticas(){return QuantidadeDeAulasPraticas;} public int getQuantidadeAulasDistancia(){return QuantidadeDeAulasDistancia;} public void setNome(String v){Nome = v.toUpperCase();} public String getNome(){return Nome;} public void setCodigo(String v){Codigo=v;} public String getCodigo(){return Codigo;} public void addPreRequisitoNecessario(Disciplina v) { if (tenhoPreRequisitoNecessario(v) == false) { preRequisitoNecessarios.add(v); v.souPreRequisito(this); } } public void removePreRequisitoNecessario(Disciplina v) { preRequisitoNecessarios.remove(v); v.deQuemSoupreRequisito.remove(this); } public Vector getPreRequisitos(){return preRequisitoNecessarios;} public boolean tenhoPreRequisitoNecessario(Disciplina v) { return preRequisitoNecessarios.contains(v);} public boolean souPreRequisito(Disciplina v) { return deQuemSoupreRequisito.contains(this);} public { void listaPreRequisitosNecessarios() int i=0; System.out.println("\nQuantidade de Pre-Requisitos Necessarios:" +preRequisitoNecessarios.size() +"\n"); for ( i = 0; i < preRequisitoNecessarios.size(); i++) { System.out.println("\n Codigo: " + ((Disciplina)this.preRequisitoNecessarios.get(i)).getCodigo() UTFPR – DAELN - Disciplina de Fundamentos de Programação II ( IF62C ). 8 Prof. Robinson Vida Noronha e Danillo Belmonte Tema: Implementação de Classe e Auto-Relacionamentos em Java ---------------------------------------------------------------------------------------------------------------------------------------------+ "\t Nome: " + ((Disciplina)this.preRequisitoNecessarios.get(i)).getNome() ); } } public void listaDeQuemSouPreRequisito() { int i=0; System.out.println("Quantidade de Disciplinas em que sou Pre-Requisito: " + this.deQuemSoupreRequisito.size() + "\n" ); for ( i = 0; i < this.deQuemSoupreRequisito.size(); i++) { System.out.println("\n Codigo: " + ((Disciplina)this.deQuemSoupreRequisito.get(i)).getCodigo() + "\t Nome: " + ((Disciplina)this.deQuemSoupreRequisito.get(i)).getNome() ); } } public boolean equals(Disciplina v) {boolean saida=false; if (v.getCodigo().equals(Codigo)) if (v.getNome().equals(Nome)) if (v.QuantidadeAulasTeoricas == this.QuantidadeAulasTeoricas) if (v.QuantidadeDeAulasDistancia == this.getQuantidadeAulasDistancia()) if (v.QuantidadeDeAulasPraticas == this.QuantidadeDeAulasPraticas) saida = true; return saida; } public void print() { System.out.print("\n"); for (int i = 0; i < 70; i++) System.out.print( "="); System.out.print("\n"); System.out.println( "Disciplina Codigo: " + this.Codigo + "\n" + "Disciplina Nome: " + this.Nome + "\n" UTFPR – DAELN - Disciplina de Fundamentos de Programação II ( IF62C ). 9 Prof. Robinson Vida Noronha e Danillo Belmonte Tema: Implementação de Classe e Auto-Relacionamentos em Java ---------------------------------------------------------------------------------------------------------------------------------------------+ "Disciplina Quantidade de Aulas Teoricas: " + this.QuantidadeAulasTeoricas + "\n" + "Disciplina Quantidade de Aulas Praticas: " + this.QuantidadeDeAulasPraticas + "\n" + "Disciplina Quantidade de Aulas a Distancia: " + this.QuantidadeDeAulasDistancia + "\n" + "Total das aulas: " + (this.QuantidadeAulasTeoricas + this.QuantidadeDeAulasDistancia + this.QuantidadeDeAulasPraticas) + "\n" ); listaPreRequisitosNecessarios(); listaDeQuemSouPreRequisito(); } public Disciplina clone() { Disciplina saida = new Disciplina(); saida.setCodigo(Codigo); saida.setNome(Nome); saida.setQuantidadeAulasTeoricas(QuantidadeAulasTeoricas); saida.setQuantidadeAulasPraticas(this.QuantidadeDeAulasPraticas); saida.setQuantidadeAulasDistancia(this.QuantidadeDeAulasDistancia); return saida; } } //fim do arquivo java 4.3 O Arquivo de teste Main.java package autorelacionamento; /** * * @author robinsonnoronha */ public class Main { public static void main(String[] args) { Disciplina MA61B = new Disciplina("MA61B", "Matematica 1"); MA61B.setQuantidadeAulasTeoricas(90); Disciplina MA61A= new Disciplina("MA61A","Calculo 1"); UTFPR – DAELN - Disciplina de Fundamentos de Programação II ( IF62C ). 10 Prof. Robinson Vida Noronha e Danillo Belmonte Tema: Implementação de Classe e Auto-Relacionamentos em Java ---------------------------------------------------------------------------------------------------------------------------------------------MA61A.setQuantidadeAulasTeoricas(90); Disciplina MA62A= new Disciplina("MA62A","Calculo 2"); MA62A.setQuantidadeAulasTeoricas(60); Disciplina FI63A= new Disciplina("FI63A","Fisica 3"); FI63A.setQuantidadeAulasTeoricas(45); FI63A.setQuantidadeAulasPraticas(60); FI63A.addPreRequisitoNecessario(MA61B); FI63A.addPreRequisitoNecessario(MA61A); Disciplina FI64A= new Disciplina("FI64A","Fisica 4"); FI64A.setQuantidadeAulasTeoricas(60); FI64A.addPreRequisitoNecessario(FI63A); // recebe os pre-requesitos. System.out.println( "\n Pre-requesitos da Disciplina FI63A:\n"); java.util.Vector l = FI63A.getPreRequisitos(); System.out.println("\n Quantidade de Pre-Requisitos:" + l.size() + "\n"); for(int i=0; i < l.size(); i++) { ((Disciplina)l.get(i)).print(); } System.out.println( "\n Clone:" + "\n"); Disciplina cloneFI63A = FI63A.clone(); if (cloneFI63A.equals(FI63A)==true) System.out.println("\n Iguais \n"); else System.out.println( "\n Diferentes clone e original" ); FI63A.print(); FI63A.removePreRequisitoNecessario(MA61B); FI63A.print(); } } 4.3 Resultado da Execução. Pre-requesitos da Disciplina FI63A: Quantidade de Pre-Requisitos:2 ====================================================================== Disciplina Codigo: MA61B Disciplina Nome: MATEMATICA 1 UTFPR – DAELN - Disciplina de Fundamentos de Programação II ( IF62C ). 11 Prof. Robinson Vida Noronha e Danillo Belmonte Tema: Implementação de Classe e Auto-Relacionamentos em Java ---------------------------------------------------------------------------------------------------------------------------------------------Disciplina Quantidade de Aulas Teoricas: 90 Disciplina Quantidade de Aulas Praticas: 0 Disciplina Quantidade de Aulas a Distancia: 0 Total das aulas: 90 Quantidade de Pre-Requisitos Necessarios:0 Quantidade de Disciplinas em que sou Pre-Requisito: 0 ====================================================================== Disciplina Codigo: MA61A Disciplina Nome: CALCULO 1 Disciplina Quantidade de Aulas Teoricas: 90 Disciplina Quantidade de Aulas Praticas: 0 Disciplina Quantidade de Aulas a Distancia: 0 Total das aulas: 90 Quantidade de Pre-Requisitos Necessarios:0 Quantidade de Disciplinas em que sou Pre-Requisito: 0 Clone: Iguais ====================================================================== Disciplina Codigo: FI63A Disciplina Nome: FISICA 3 Disciplina Quantidade de Aulas Teoricas: 45 Disciplina Quantidade de Aulas Praticas: 60 Disciplina Quantidade de Aulas a Distancia: 0 Total das aulas: 105 Quantidade de Pre-Requisitos Necessarios:2 Codigo: MA61B Nome: MATEMATICA 1 Codigo: MA61A Nome: CALCULO 1 Quantidade de Disciplinas em que sou Pre-Requisito: 0 ====================================================================== Disciplina Codigo: FI63A Disciplina Nome: FISICA 3 Disciplina Quantidade de Aulas Teoricas: 45 Disciplina Quantidade de Aulas Praticas: 60 Disciplina Quantidade de Aulas a Distancia: 0 Total das aulas: 105 Quantidade de Pre-Requisitos Necessarios:1 Codigo: MA61A Nome: CALCULO 1 Quantidade de Disciplinas em que sou Pre-Requisito: 0 UTFPR – DAELN - Disciplina de Fundamentos de Programação II ( IF62C ). 12 Prof. Robinson Vida Noronha e Danillo Belmonte Tema: Implementação de Classe e Auto-Relacionamentos em Java ---------------------------------------------------------------------------------------------------------------------------------------------BUILD SUCCESSFUL (total time: 0 seconds) 5. Exercício a) Implementar e testar a classe Pessoa e o Auto-Relacionamento “casada_com”. b) A Classe Pessoa do exercício 5 foi modificada, para o Exercício 5b) Além do Auto-relacionamento “cada_com” com multiplicidade “0..1”, um novo AutoRelacionamento deve ser implementado. Esse novo Auto-Relacionamento é denominado “amizadeCom” e possui multiplicidade “0..*”. Modificar a classe Pessoa implementada no exercício 5a) de tal forma que ela represente esse novo Diagrama de Classe. UTFPR – DAELN - Disciplina de Fundamentos de Programação II ( IF62C ). 13 Prof. Robinson Vida Noronha e Danillo Belmonte Tema: Implementação de Classe e Auto-Relacionamentos em Java ---------------------------------------------------------------------------------------------------------------------------------------------- 6. Anexos a) b) UTFPR – DAELN - Disciplina de Fundamentos de Programação II ( IF62C ). 14 Prof. Robinson Vida Noronha e Danillo Belmonte Tema: Implementação de Classe e Auto-Relacionamentos em Java ---------------------------------------------------------------------------------------------------------------------------------------------- c) d) e)