Uml

Não. Significa que em algum momento a classe dependente “usa” a classe independente, mas não mantém referências a objetos da classe em seus atributos. Podemos estabelecer dependência entre a classe A com relação à B quando:

[list] a classe A recebe algum objeto da classe B como parâmetro [/list]
[list] a classe A instância um objeto da classe B localmente em um dos seus métodos [/list]
[list] a classe A invoca um método static da classe B [/list]

O modelo mostrado não indica que ha relação de herança entre essas classes. O modelo postado é completamente válido em relação à relações descritas nos requisitos ( enunciado). A menos que herança faça parte dos requisitos não ha mal em a evitar.

É uma má prática incluir regras que não são ditadas pelos requisitos. Cuidado com isso.[/quote]

:arrow: as pessoas podem ser aluno, professor ou funcionário.
[/quote]

Os requisitos ( o enuncidado) não se refere a pessoa. Logo, “pessoa” não é uma entidade do modelo. Portanto, criá-la é incluir regras não ditadas pelos requisitos. Isso é uma má prática e deve ser evitado.

As pessoas podem ser aluno etc… mas aluno , professor, etc… não devem ser pessoas neste modelo.
“Dever” é mais forte que “Poder” e por isso que é uma má prática incluir coisas apenas porque pode.

O modelo mostrado não indica que ha relação de herança entre essas classes. O modelo postado é completamente válido em relação à relações descritas nos requisitos ( enunciado). A menos que herança faça parte dos requisitos não ha mal em a evitar.

É uma má prática incluir regras que não são ditadas pelos requisitos. Cuidado com isso.[/quote]

:arrow: as pessoas podem ser aluno, professor ou funcionário.
[/quote]

Os requisitos ( o enuncidado) não se refere a pessoa. Logo, “pessoa” não é uma entidade do modelo. Portanto, criá-la é incluir regras não ditadas pelos requisitos. Isso é uma má prática e deve ser evitado.

As pessoas podem ser aluno etc… mas aluno , professor, etc… não devem ser pessoas neste modelo.
“Dever” é mais forte que “Poder” e por isso que é uma má prática incluir coisas apenas porque pode.[/quote]

:arrow: Sistema para uma escola onde deve permitir o cadastro de pessoas, as pessoas podem ser aluno, professor ou funcionário.

Bem sergiotaborda, vai me desculpar, mas para mim está bem claro que no enunciado que Pessoa é uma entidade e Aluno , Professor e Funcionário são casos específicos de pessoa. Eu não estou inventando nada, nem incluindo regras que não estão nos requisitos. Acho que a discussão seria bastante enriquecida se você postasse a sua proposta de solução. Ademais, ninguém melhor que o autor do tópico para esclarecer o enunciado.

O modelo mostrado não indica que ha relação de herança entre essas classes. O modelo postado é completamente válido em relação à relações descritas nos requisitos ( enunciado). A menos que herança faça parte dos requisitos não ha mal em a evitar.

É uma má prática incluir regras que não são ditadas pelos requisitos. Cuidado com isso.[/quote]

:arrow: as pessoas podem ser aluno, professor ou funcionário.
[/quote]

Os requisitos ( o enuncidado) não se refere a pessoa. Logo, “pessoa” não é uma entidade do modelo. Portanto, criá-la é incluir regras não ditadas pelos requisitos. Isso é uma má prática e deve ser evitado.

As pessoas podem ser aluno etc… mas aluno , professor, etc… não devem ser pessoas neste modelo.
“Dever” é mais forte que “Poder” e por isso que é uma má prática incluir coisas apenas porque pode.[/quote]

:arrow: Sistema para uma escola onde deve permitir o cadastro de pessoas, as pessoas podem ser aluno, professor ou funcionário.

Bem sergiotaborda, vai me desculpar, mas para mim está bem claro que no enunciado que Pessoa é uma entidade e Aluno , Professor e Funcionário são casos específicos de pessoa.[/quote]

Veja bem, vc tem o cadastro de Pessoa ? Ou seja, vc tem uma tela para cadastar “pessoa” ? Ou tem uma tela para aluno, outra para professor e outra para funcionário ?

Se vc tiver uma só tela vc tem razão, pessoa é uma entidade. Se vc tem 3, então não tem razão.
Se vc tem uma só tela e pessoa é uma entidade , então Aluno, Professor e Funcionário são tipos e não subclasses. Logo, o modelo que vc propoe estaria errado da mesma forma.

O ponto é: o enunciado não força vc a usar herança entre pessoa , aluno, prof e funcionario, então não use.
O modelo original do primeiro post propoe que aluno, funcionario e prof tenha um objeto pessoa. Isso é aceitável. Esse era o meu ponto. Não ha que forçar herança. Mas se vc gosta de usar herança, be my guest

Peraí … se eu entendi bem, a sua proposta é resolver com composição ? Ou seja, um Aluno TEM uma Pessoa, um Professor TEM uma Pessoa , etc. É isso ?

Não. Essa foi a do autor do primeiro post.
E falaram que tinha que usar herança. Eu so estou dizendo que não ha nada de errado em não usar herança, ou seja , a proposta original funciona. (excepto a parte de util referenciar pessoa, mas isso já foi resolvido)

Na realidade a minha proposta seria - se tivesse feito alguma - ignorar pessoa e criar 3 classes separadas.

Ah sim, agora eu entendi! De fato, as três abordagens (composição , herança , e as 3 classes separadas ) funcionam. Em um primeiro momento, as classes aluno, professor e funcionário são diferentes. Também concordo que nada obriga a utilização da herança. Mas concordo comigo , que é possível generalizar as três classes em uma superclasse pessoa, uma vez que há atributos e comportamentos comuns entre as 3 ?Essa classe Pessoa pode ser uma classe abstrata, assim você não pode ter objetos pessoa. Na minha opinião, implementar as 3 classes separadas vai inserir pequeno overhead, pois você vai ter que repetir código.

Sergio, ao meu ver e pelo que fui aconselhado má prática é ignorar partes do enunciado, mas não ter uma “saída elegante” para o que é proposto.
Se estamos falando de OO estamos falando em reutilização de código e herança entra nesse ponto. Para o que foi proposto, como disse o rmendes08, acredito que herança seja a melhor implementação.
Criar três classes é perda de tempo e re-trabalho.

Abraços,

Isso que vc explicou constitui um erro de entendimento de quem começa com orientação a objetos. A pessoa acha que porque estamos usando OO tudo tem que ser filho de algo e tudo tem que ser polimorfico. Pensar assim é ingénuo pois na realdiade não é assim que os problemas se solucionam. Herança não serve para reaproveitar código. Eu sei que isso é o que se passa nos cursinho básicos de OO, mas não é para isso que ela serve. O reaproveitamento de código é um efeito secundário do uso de herança. A herança não deve ser usada apenas porque estou vislumbrando código semelhante espalhado em classes diferentes.
Isso é uma armadilha e foi em relação a isso que tentei chama a atenção.

Não se trata de ignorar mas sim de analizar e sintetizar Existe valor em colocar a classe Pessoa no modelo ? No caso não existe.
A menos que seja um requisito explicito - “construa aluno, funcionario e professor como classes que herdem de pessoa” - tudo é discutivel. O ponto de equilibrio é não complicar demais as coisas usando artificios como a herança. Vc precisa de um motivo, no modelo, para usar herança e não razões de ordem tecnica como “aproveitar codigo”. Herança não é remédio para a preguiça.

Não é por acaso que esse passo do desenvolvimento se chama análise. Mas análise é inutl sem uma sintese.
enquanto vc não pode ignorar nada durante a analise, vc precisa se livrar do lastro durante a sintese.

Mas não aceitem a minha palavra. Experimentem construir o sistema das 3 formas e vejam qual é mais simples.

Pelo visto o meu “cursinho básico de OO” foi um bosta mesmo, pois não citaram ganhos mais importantes para usar herança que não fossem reutilização de código e manutenção de código.

Se possível gostaria que me informasse qual/quais os efeitos primários da utilização de herança, visto que, como você disse, reutilização é secundário.

Herança não é remédio para a preguiça, mas é remédio para ganho de produtividade, ganho de tempo. E ambos estão inerentes ao desenvolvimento.

E aqui a questão não é aceitar ou não aceitar sua palavra. Estamos em um forum, o qual é voltado pra discussão, portanto, subentende-se que cada um pode expressar sua opinião pra que a mesma possa ser discutida. Não estou convencido que usar herança no problema do amigo é uma “fuga” do enunciado, mas gostaria que me convencessem disso.

Abraços,

[quote=pimenta]Pelo visto o meu “cursinho básico de OO” foi um bosta mesmo, pois não citaram ganhos mais importantes para usar herança que não fossem reutilização de código e manutenção de código.

Se possível gostaria que me informasse qual/quais os efeitos primários da utilização de herança, visto que, como você disse, reutilização é secundário.

Herança não é remédio para a preguiça, mas é remédio para ganho de produtividade, ganho de tempo. E ambos estão inerentes ao desenvolvimento.

E aqui a questão não é aceitar ou não aceitar sua palavra. Estamos em um forum, o qual é voltado pra discussão, portanto, subentende-se que cada um pode expressar sua opinião pra que a mesma possa ser discutida. Não estou convencido que usar herança no problema do amigo é uma “fuga” do enunciado, mas gostaria que me convencessem disso.
[/quote]

Não disse que era um fuga. Apenas chamei a atenção para que; usar herança para apenas reaproveitar codigo é uma má prática. E para terem cuidado com esse tipo de modelagem. Como isto é um forum básico, o meu objetivo foi só chamar a atenção.

O uso de herança é restrito à necessidade de polimorfismo. Ou seja, quando eu quero tratar coisas diferentes como se fossem iguais. Normlmente eu preciso abstrair essas coisas diferentes e encontrar uma parente comum.

Se o modelo tivesse necessidade de um processo fazAlgumaCoisaAAluno(Aluno a) e depois um outro fazAlgumaCoisaAProfessor(Professor pf) e um outro fazAlgumaCoisaAFuncionario(Funcionario f) e o que o processo fizesse fosse exactamente a mesma coisa, ou apenas ligeiramente diferente ( um if de diferença) seria util inventar um fazAlgumaCoisaA(Pessoa p). Nestas circusntancias, e apenas nestas circunstancias, em que tenho necessidade de algo mais abstrato é que eu coloca o tipo Pessoa na mistura. E para começar ela é uma interface ( programação para interface). Não necessito de mais do que aquilo que uma interface me dá. Não preciso saltar direto para herança de classe.
Conforme novos processo vão sendo descobertos e à medida de que a necessidade cresce pode ser necessário tornar Pessoa uma classe em vez de um interface. Um motivo simples é: Aquilo que é pessoa não pode ser nada mais. Então ai, quando eu sei que posso gastar a minha única herança , eu crio Pessoa como uma classe abstrata e faço Aluno, etc… herdar dela.

Houve reaproveitamento de código aqui ? Sim. eu reaproveitei tudo o codigo dentro de fazAlgumaCoisaA() , tenho ganho em produtividade e manutenção ? sim. Só tenho um único método e só tenho que manter um único método. Houve alguma tentativa de aproveitar/fundir codigo dentro das classes Aluno, Professor, etc… ? Não. Não houve.

O ganho mais importante é polimorfismo. Com o polimorfismo vc obtem outros ganhos de forma natural pela propria estrutrua do java e da OO, mas eu não procurei usar herança para agrupar atributos comuns de aluno, professor, etc… eu a usei para facilitar a escrita de fazAlgumaCoisaA()

Como no modelo do topico não existe esse método que necessite de algo polimorfico, não ha porquê usar herança.
Agora vc me diz : mas todos têm cpf, nome, etc… não dá para agrupar isso ?
Sim, dá. Vc cria uma classe DadosDemograficos e coloca tudo isso lá. Ai, cada classe dessas terá um DadosDemograficos em vez de N atributos. Isso pode ser suficiente em muitos mais casos do que imagina. E sem recorrer a herança.

Agora que entendeu, imagine que o fazAlgumaCoisa era enviaEmailPara() eu preciso de saber o endereço e o nome da pessoa para quem estou enviando. Será que o meu DadosDemograficos resolve ? sim, resolve

class XPTO {

 public void enviaEmailPara( DadosDemograficos  dd ) {

         Email email = new Email() // classe ficiticia
        email.setAddress( dd.getEmail());
        email.setText("Olá , " + dd.getName() );
        email.send();
 }
}

Sem herança eu tenho apenas um só método que serve para todos os tipos de “pessoa”.

Agora que vc entendeu isso vc me diria: EnviaEmailPara(DadosDemograficos) é meio estranho, envian-se emaisl para pessoas.
Ok, então crie a interface Pessoa assim

interface Pessoa {

  public DadosDemograficos getDadosDemograficos();
}

e faça Aluno, etc… implementá-la. Altere o método para receber Pessoa e puxe os dados demograficos dentro do método.

Isto não altera em nada o que as suas classes já faziam ( elas já tinham esse método) mas vc ganhou polimorfismo.

Isto é um exemplo simples. O ponto é que herança é algo muito mais forte e poderoso do que se pode pensar à primeira vista.
Por isso que a herança não é multipla em java. É um recurso de ultimo recurso. É aquela arma que vc guarda para enfrentar o boss no fim do jogo. Se vc a usa cedo demais, depois vc se ferra.

Java lhe dá muitas mais ferramentas do que herança, e mais baratas. Então use-as. Não se precipite a usar herança só porque vc vê atributos comuns em uma classe.


Bom, dito tudo isto: vc poderia em vez de chamar de DadosDemograficos chamar diretamente de Pessoa. Que foi o que o modelo original fez. O objetivo de criar aquela classe é agrupar atributos e isso não se resolve com herança. Por isso o modelo é válido.
Mas usar o nome “Pessoa” para essa classe de agrupamento cria uma confusão automática pq a palavra “Pessoa” transmite um conceito de herança quase que automáticamente. E dai toda esta confusão. Por isso que modelar não é tão simples quanto parece… :wink:

Conceitos são mais importantes que palavras. Quando vc vir “Pessoa” em um modelo pense: o que está sendo feio ali ? Agrupar atributos ? Então não deve ser usada herança. Pelo menos não sem uma muito boa razão. Só o resto do modelo lhe pode dar essa razão.

No caso do enunciado, não ha essa razão

Realmente sergiotaborda, esse último post esclareceu bastante. Essa reflexão sobre o uso de herança é um bom tema para um artigo.

Sem mais.
Reduzo-me à minha insignificância. (dramático… aiuhauhauha)

Sérgio, formata isso num arquivinho e veja se os moderadores não podem disponibilizá-lo aqui. Muito bom. E realmente… faltava alguma coisa no meu conceito, justamente o detalhe. E como diz um amigo meu: O detalhe é sempre o que vale!

Abraços,

Muito obrigado a todos vocês, a cada dia que leio o texto de Sergiotaborda, minha visão de OOP vai amadurecendo.Paz e saúde para todos vocês!

Junio César Silva

Bom dia,

Sergiotaborda, estou engadinhando em Java, seu texto foi de grande valia, achei confortável para eu desenvolver utilizando herança, mas quero utilizar depois a interface.Tenho a classe Pessoa, e classe Aluno que herdam os seus atributos, gostaria de saber o porque ele não está importando a classe Util.
Classe Pessoa:

public class Pessoa {
	private int cpf;
	private String dataNascimento;
	private String nome;
	private String endereco;
	
		public Pessoa(int cpf, String dataNascimento, String nome, String endereco){
			setAge (cpf);
			setDatanascimento (dataNascimento);
			setNome(nome);
			setEndereco (endereco);			
		}
		
		public void setAge (int cpf){
			this.cpf = cpf;
		}
		public void setDatanascimento (String dataNascimento){
			this.dataNascimento = dataNascimento;
		}
		public void setNome (String nome){
			this.nome = nome;
		}
		public void setEndereco (String endereco){
			this.endereco = endereco;
		}
		
		public int getAge (){
			return cpf;
		}
		public String getDatanascimento (){
			return dataNascimento;
		}
		public String getNome (){
			return nome;
		}
		public String getEndereco (){
			return endereco;
		}
	

}

Classe Aluno:

import static Util.*;
public class Aluno extends Pessoa {
	private int anoInicioGraduacao;
	
	public Aluno (int cpf, String dataNascimento, String nome, String endereco){
		super (cpf, dataNascimento, nome, endereco);
		setAnoiniciograduacao (anoInicioGraduacao);
	}
	
	public void setAnoiniciograduacao (int anoInicioGraduacao){
		this.anoInicioGraduacao = anoInicioGraduacao;
	}
	public int getAnoiniciograduacao (){
		return anoInicioGraduacao;
	}
	
	public void exibir (){
		System.out.println ("----------------------------------------------------------------");
		System.out.println ("CPF: " + getAge ());
		System.out.println ("Data de Nascimento: " + getDatanascimento ());
		System.out.println ("Nome: " + getNome ());
		System.out.println ("Endereco: " + getEndereco ());
		System.out.println ("Ano Inicio Graduacao: " + getAnoiniciograduacao ());			
	}
	
	public static void main (String[] args){
		Aluno a = new Aluno(1240548840, "22/05/1982", "Antonio", "Rua dois,nº123, Bairro Lagoa, Betim/MG");
		a.setAnoiniciograduacao(2000);
		a.exibir();
		Aluno b = new Aluno(1240548840, "22/05/1982", "Antonio", "Rua dois,nº123, Bairro Lagoa, Betim/MG");
		b.setAnoiniciograduacao(2000);
		b.exibir();
		Aluno c = new Aluno(1240548840, "22/05/1982", "Antonio", "Rua dois,nº123, Bairro Lagoa, Betim/MG");
		c.setAnoiniciograduacao(2000);
		c.exibir();
		Aluno d = new Aluno(1240548840, "22/05/1982", "Antonio", "Rua dois,nº123, Bairro Lagoa, Betim/MG");
		d.setAnoiniciograduacao(2000);
		d.exibir();
		Aluno e = new Aluno(1240548840, "22/05/1982", "Antonio", "Rua dois,nº123, Bairro Lagoa, Betim/MG");
		e.setAnoiniciograduacao(2000);
		e.exibir();
	}

}

Classe Util:

import java.util.Date;
import java.util.Calendar;
public class Util {
	public static int getAge(Date date1) {
		int age = 0;
		Calendar birthdate = Calendar.getInstance();
		birthdate.setTime(date1);
		Calendar now = Calendar.getInstance();
		age = now.get(Calendar.YEAR) - birthdate.get(Calendar.YEAR);
		birthdate.add(Calendar.YEAR, age);
		if (now.before(birthdate))
		age--;
		return age;
		} 

}

Agradeço desde já,

Júnio César Silva

Muito bom mesmo sergio, parabens !

Static ?

import static Util.*;   

Faz um tempinho que não mecho com java, mas não seria assim?:

import java.Util.*;   

Seria assim na verdade:

import java.util.Util;

Bom dia amigos,

Está aparecendo a mensagem:“The import java.util.Util cannot be resolved” ou “The import java.Util cannot be resolved”.

Agradeço a todos pela atenção.

[quote=juniomundo]Bom dia,

Sergiotaborda, estou engadinhando em Java, seu texto foi de grande valia, achei confortável para eu desenvolver utilizando herança, mas quero utilizar depois a interface.Tenho a classe Pessoa, e classe Aluno que herdam os seus atributos, gostaria de saber o porque ele não está importando a classe Util.
[/quote]

O que vc quer dizer com “não está importanto a classe Util” ?
Existem várias coisas a melhorar no seu codigo.
Para começar porque o CPF é passado em setAge() ? Não faz sentido.
Depois, setAge por si não faz sentido. Se vc tem a data de nascimento, calcule a ideia usando a função de Util.
Vc não está usando essa função em lugar algum.
Não precisa ter uma classe Util para calcular a idade , inclua-a como private static em Pessoa
Use java.util.Date para datas e não String.
Use String para CPF e não int. (melhor ainda crie uma classe CPF)

Classe Pessoa:

public class Pessoa {
	private String cpf; // use String
	private Date dataNascimento; // use Date
	private String nome;
	private String endereco;
	
		public Pessoa(String cpf, Date dataNascimento, String nome, String endereco){
			this.cpf = cpf;  //  não crie setXXX a menos que necessário e não use métodos polimorficos no construtor
			this.dataNascimento = dataNascimento;
			this.nome = nome;
			this.endereco = endereço;			
		}
		
                // calcula a idade,em anos, na data passada
		public int getAge (Date date){
			return calculateAge(date,dataNascimento);
		}

                // calcula idade, em anos, exactamente agora
                public int getAge (){
			return calculateAge(new Date(), dataNascimento);
		}
		
	       private static int calculateAge(Date day, Date birthday){
                   // calculos 

              }

}