UTFPR DAELN - Disciplina de Fundamentos de Programação II ( IF62C ). 1 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 Auto- Relacionamento. 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 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 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 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 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 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 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 + "\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 + "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 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 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 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 Auto- Relacionamento 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 6. Anexos a) b)
UTFPR DAELN - Disciplina de Fundamentos de Programação II ( IF62C ). 14 c) d) e)