[RESOLVIDO] Como contornar a herança múltipla em JAVA?[RESOLVIDO]

Boa Tarde Caros!

Estou com um questionamento a vários dias, tentando arrumar uma maneira de contornar a herança múltipla em java,
pela teoria, eu sei devo utilizar interface, mas na prática a teoria é outra, ainda não consegui aplicar esse conceito.
Segue abaixo o exemplo:

//Classe Profissão//

public class Profissao {

	private float cargaHoraria;
	private float salario;

	public Profissao(float cargaHoraria, float salario) {
		this.cargaHoraria = cargaHoraria;
		this.salario = salario;
	}

}

//Classe Professor

public class Professor extends Profissao {
	
	private int matricula;
	
	public Professor(float cargaHoraria, float salario, int matricula)
	{
		super(cargaHoraria, salario);
		this.matricula = matricula;
	}

}

//Classe Bolsista//

public class Bolsista extends Profissao {
	
	private int ra;
	
	public Bolsista(float cargaHoraria, float salario, int ra)
	{
		super(cargaHoraria, salario);
		this.ra = ra; 
		
	}

}

// Classe Pesquisador //

public class Pesquisador{

}

// Interface IBolsista //

[code]
public interface IBolsista{

}[/code]
//Interface IProfessor//

[code]
public interface IProfessor{

}[/code]

Esse exemplo acima ilustra a situação que um pesquisador atua como professor e bolsista ao mesmo tempo, cada um tem suas características específicas.

Como eu posso resolver isso?

Muito obrigado,

Att, André Vieira.

cara,

se vc tomar essa abordagem nao resolveria seu problema, Professor TEM uma profissao e É uma pessoa, sua classe ficaria assim

public class Professor extends Pessoa{  
      
    private int matricula;  
    private Profissao profissao;
  
}

t+

[quote=alissonvla]cara,

se vc tomar essa abordagem nao resolveria seu problema, Professor TEM uma profissao e É uma pessoa, sua classe ficaria assim

public class Professor extends Pessoa{  
      
    private int matricula;  
    private Profissao profissao;
  
}

t+[/quote]

Muito obrigado pela resposta, entretanto Pessoa está muito longe até onde eu quero chegar, há muito ancestrais, eu mencionei minha ideia errada,
altere essa classe “Pessoa” por “Pesquisador”.

Entendeu até onde eu quero chegar? Eu quero utilizar a interface para contornar o problema de herança múltipla…

cara,

fica dificil eu te dar uma reposta sem conhecer sobre seu negocio, pq pra mim um pesquisador é um tipo de profissao, como professor e bolsista.

t+

[quote=alissonvla]cara,

fica dificil eu te dar uma reposta sem conhecer sobre seu negocio, pq pra mim um pesquisador é um tipo de profissao, como professor e bolsista.

t+[/quote]

Então, pense que pesquisador herde características específicas encontradas no professor e no bolsista ao mesmo tempo, afinal bolsista não é professor e vice-versa, você concorda?

Muito obrigado!

Att,

André Vieira.

Acho que você está usando herança de maneira errada! Para usar herança as classes que herdam “são a a classe ancestral”. Mas o ser um pode ser um problema. Olhe o exemplo abaixo:

  1. Totó é um beagle
  2. Beagle é um cachorro
  3. Cachorro é um animal
  4. Beagle é uma raça
  5. Cachorro é uma espécie.

Combinando 1 e 2 eu tenho que “Totó é um cachorro” e a 2 e 3 juntas daria "Beagle é um animal"
A frase 1, 2 e 3 juntas daria “Totó é um animal”!

Agora se a gente juntar as frases 1 e 4 daria “Totó” é uma raça" e a frase 2 e 5 daria “Beagle é uma espécie”!

O problema é que estamos confundindo generalização com classificação e isso é muito comum, até mesmos profissionais experientes se confundem. No caso acima o correto seria:

  1. Totó é um um cachorro

  2. Cachorro é um animal

  3. Beagle é uma raça

  4. Especie contém animais

Então poderiamos fazer que cachorro TER UMA RACA, assim Totó poderia SER CLASSIFICADO como um Beagle!

Essa é a diferença entre SER UM e TER UM, SER CLASSIFICADO COMO UM!

No seu caso acredito que Pesquisador pode ser classificado como tendo uma Profissão! Assim como uma pessoa pode ter mais de uma profissão um pesquisador também poderia ter mais de uma, podendo ao mesmo tempo ser um professor e um bolsista!

SEMPRE PRIORIZE A COMPOSIÇÃO A HERANÇA!

No seu caso acredito até mesmo que Pesquisador seja uma profissão. Acredito que esteja faltando uma terceira classe em seu domínio, algo como funcionário. Um funcionário tem uma profissão ou várias, ou seja, um funcionário pode ser classificado como um professor, um bolsista, um pesquisador ou até mesmo os três ao mesmo tempo!

PS: O Exemplo eu li a algum tempo em um livro do Martin Fowler, se não me engano foi no UML Essencial

[quote=x@ndy]Acho que você está usando herança de maneira errada! Para usar herança as classes que herdam “são a a classe ancestral”. Mas o ser um pode ser um problema. Olhe o exemplo abaixo:

  1. Totó é um beagle
  2. Beagle é um cachorro
  3. Cachorro é um animal
  4. Beagle é uma raça
  5. Cachorro é uma espécie.

Combinando 1 e 2 eu tenho que “Totó é um cachorro” e a 2 e 3 juntas daria "Beagle é um animal"
A frase 1, 2 e 3 juntas daria “Totó é um animal”!

Agora se a gente juntar as frases 1 e 4 daria “Totó” é uma raça" e a frase 2 e 5 daria “Beagle é uma espécie”!

O problema é que estamos confundindo generalização com classificação e isso é muito comum, até mesmos profissionais experientes se confundem. No caso acima o correto seria:

  1. Totó é um um cachorro

  2. Cachorro é um animal

  3. Beagle é uma raça

  4. Especie contém animais

Então poderiamos fazer que cachorro TER UMA RACA, assim Totó poderia SER CLASSIFICADO como um Beagle!

Essa é a diferença entre SER UM e TER UM, SER CLASSIFICADO COMO UM!

No seu caso acredito que Pesquisador pode ser classificado como tendo uma Profissão! Assim como uma pessoa pode ter mais de uma profissão um pesquisador também poderia ter mais de uma, podendo ao mesmo tempo ser um professor e um bolsista!

SEMPRE PRIORIZE A COMPOSIÇÃO A HERANÇA!

No seu caso acredito até mesmo que Pesquisador seja uma profissão. Acredito que esteja faltando uma terceira classe em seu domínio, algo como funcionário. Um funcionário tem uma profissão ou várias, ou seja, um funcionário pode ser classificado como um professor, um bolsista, um pesquisador ou até mesmo os três ao mesmo tempo!

PS: O Exemplo eu li a algum tempo em um livro do Martin Fowler, se não me engano foi no UML Essencial[/quote]

É então talvez eu estaria violando o princípio de Liskov, entretanto, abrindo o jogo,
eu tenho um exercício da faculdade, que pensei o problema seria herança múltipla( letra a. ), então tenho que defender esse princípio via código em java,
na teoria, eu sei que deve utilizar interface, mas na prática não sei como fazer isso, pois nunca precisei fazer isso.

O exercício pode ser visualizado abaixo:

Um professor do curso X de uma universidade privada no período noturno se torna um bolsista do curso Y no período matutino da mesma Universidade.

a) A situação citada causa que tipo de problema em um projeto de sistema de software? Explique. Qual seria a solução para este problema?

b) Represente a solução em um diagrama de classes. Explique.

c) Apresente a estrutura básica de código em JAVA, C# ou C++ para implementar a solução.

O que você acha da minha ideia? Qual a sua opinião perante a esse exercício?

Muito obrigado!

Att, André Vieira

Galera muito obrigado pela ajuda de vocês, sem ela acho que não teria conseguido.

Para aqueles que tiverem o mesmo questionamento que eu, apresento o código que é mais fácil de ser visualizado.

Isso que eu queria fazer, mas a tarde irie refinar esse código.

[code]
public class Profissao {
private float cargaHoraria;
private float salario;

public Profissao(float cargaHoraria, float salario) {  
    this.cargaHoraria = cargaHoraria;   
    this.salario = salario;  
}  

public float getCargaHoraria() {  
    return cargaHoraria;  
}  

public void setCargaHoraria(float cargaHoraria) {  
    this.cargaHoraria = cargaHoraria;  
}  

public float getSalario() {  
    return salario;  
}  

public void setSalario(float salario) {  
    this.salario = salario;  
}  

}

public class Professor extends Profissao {

private int matricula;  
  
public Professor(float cargaHoraria, float salario, int matricula)  
{  
    super(cargaHoraria, salario);  
    this.matricula = matricula;  
}  

public int getMatricula() {  
    return matricula;  
}  

public void setMatricula(int matricula) {  
    this.matricula = matricula;  
}  

}

public class Bolsista extends Profissao implements IBolsista {

private int ra;  
  
public Bolsista(int ra, float cargaHoraria, float salario)  
{  
    super(cargaHoraria, salario);  
    this.ra = ra;   
}  
  
public int getRa()  
{  
    return ra;   
}  
public String imprimirDados()  
{  
    return "O ra: "+ra+"| A cargaHoraria: "+getCargaHoraria()+"| O salario: "+getSalario()+"|." ;  
}  

}
public class Pesquisador extends Professor implements IBolsista{

private IBolsista iBolsista;  
  
public Pesquisador(float cargaHoraria, float salario, int matricula, IBolsista iBolsista) {  
    super(cargaHoraria, salario, matricula);  
    // TODO Auto-generated constructor stub  
    this.iBolsista = iBolsista;  
}  
  
public int getRa()  
{  
    return iBolsista.getRa();   
}  
public String imprimirDados()  
{  
    return iBolsista.imprimirDados()+"A matrícula: "+getMatricula()+" |";  
}  

}

public class Main {

/** 
 * @param args 
 */  
public static void main(String[] args) {  
    // TODO Auto-generated method stub  
    float cargaHoraria=100;  
    float salario=100;  
    int matricula=111;  
    int ra=111;   
      
    Bolsista objB = new Bolsista(ra,cargaHoraria,matricula);  
      
    Pesquisador objP = new Pesquisador(cargaHoraria,salario,matricula, objB);  
      
    System.out.println(objP.imprimirDados());   
      
}  

} [/code]

[quote=Andr?de Souza Vieira]Galera muito obrigado pela ajuda de vocês, sem ela acho que não teria conseguido.

Para aqueles que tiverem o mesmo questionamento que eu, apresento o código que é mais fácil de ser visualizado.

Isso que eu queria fazer, mas a tarde irie refinar esse código.

[code]
public class Pesquisador extends Professor implements IBolsista{

private IBolsista iBolsista;  
  
public Pesquisador(float cargaHoraria, float salario, int matricula, IBolsista iBolsista) {  
    super(cargaHoraria, salario, matricula);  
    // TODO Auto-generated constructor stub  
    this.iBolsista = iBolsista;  
}  
  
public int getRa()  
{  
    return iBolsista.getRa();   
}  
public String imprimirDados()  
{  
    return iBolsista.imprimirDados()+"A matrícula: "+getMatricula()+" |";  
}  

}

public class Main {

/** 
 * @param args 
 */  
public static void main(String[] args) {  
    // TODO Auto-generated method stub  
    float cargaHoraria=100;  
    float salario=100;  
    int matricula=111;  
    int ra=111;   
      
    Bolsista objB = new Bolsista(ra,cargaHoraria,matricula);  
      
    Pesquisador objP = new Pesquisador(cargaHoraria,salario,matricula, objB);  
      
    System.out.println(objP.imprimirDados());   
      
}  

} [/code][/quote]

Tem um erro no seu código você está implementando a Interface Bolsista e recebendo um Bolsista ou seja a classe É UM bolsista e TEM UM Bolsista!.

Na verdade, nesse caso, você não deveria receber um bolsista no construtor. De qualquer maneira a meu ver problema não é herança múltipla e sim o problema de classificação e versus generalização! Tanto que na letra c ele diz que pode ser implementado em C++ que permite herança multipla!

[quote=x@ndy][quote=Andr?de Souza Vieira]Galera muito obrigado pela ajuda de vocês, sem ela acho que não teria conseguido.

Para aqueles que tiverem o mesmo questionamento que eu, apresento o código que é mais fácil de ser visualizado.

Isso que eu queria fazer, mas a tarde irie refinar esse código.

[code]
public class Pesquisador extends Professor implements IBolsista{

private IBolsista iBolsista;  
  
public Pesquisador(float cargaHoraria, float salario, int matricula, IBolsista iBolsista) {  
    super(cargaHoraria, salario, matricula);  
    // TODO Auto-generated constructor stub  
    this.iBolsista = iBolsista;  
}  
  
public int getRa()  
{  
    return iBolsista.getRa();   
}  
public String imprimirDados()  
{  
    return iBolsista.imprimirDados()+"A matrícula: "+getMatricula()+" |";  
}  

}

public class Main {

/** 
 * @param args 
 */  
public static void main(String[] args) {  
    // TODO Auto-generated method stub  
    float cargaHoraria=100;  
    float salario=100;  
    int matricula=111;  
    int ra=111;   
      
    Bolsista objB = new Bolsista(ra,cargaHoraria,matricula);  
      
    Pesquisador objP = new Pesquisador(cargaHoraria,salario,matricula, objB);  
      
    System.out.println(objP.imprimirDados());   
      
}  

} [/code][/quote]

Tem um erro no seu código você está implementando a Interface Bolsista e recebendo um Bolsista ou seja a classe É UM bolsista e TEM UM Bolsista!.

Na verdade, nesse caso, você não deveria receber um bolsista no construtor. De qualquer maneira a meu ver problema não é herança múltipla e sim o problema de classificação e versus generalização! Tanto que na letra c ele diz que pode ser implementado em C++ que permite herança multipla![/quote]

Obrigado pela resposta! Tem uns errinhos sim, fiz ontem correndo,
mas fui a maneira que eu encontrei para utilizar o Professor e Bolsista a partir do pesquisador.
Vou refinar esse código mais tarde.
At+,
Abraço.

[quote=x@ndy][quote=Andr?de Souza Vieira]Galera muito obrigado pela ajuda de vocês, sem ela acho que não teria conseguido.

Para aqueles que tiverem o mesmo questionamento que eu, apresento o código que é mais fácil de ser visualizado.

Isso que eu queria fazer, mas a tarde irie refinar esse código.

[code]
public class Pesquisador extends Professor implements IBolsista{

private IBolsista iBolsista;  
  
public Pesquisador(float cargaHoraria, float salario, int matricula, IBolsista iBolsista) {  
    super(cargaHoraria, salario, matricula);  
    // TODO Auto-generated constructor stub  
    this.iBolsista = iBolsista;  
}  
  
public int getRa()  
{  
    return iBolsista.getRa();   
}  
public String imprimirDados()  
{  
    return iBolsista.imprimirDados()+"A matrícula: "+getMatricula()+" |";  
}  

}

public class Main {

/** 
 * @param args 
 */  
public static void main(String[] args) {  
    // TODO Auto-generated method stub  
    float cargaHoraria=100;  
    float salario=100;  
    int matricula=111;  
    int ra=111;   
      
    Bolsista objB = new Bolsista(ra,cargaHoraria,matricula);  
      
    Pesquisador objP = new Pesquisador(cargaHoraria,salario,matricula, objB);  
      
    System.out.println(objP.imprimirDados());   
      
}  

} [/code][/quote]

Tem um erro no seu código você está implementando a Interface Bolsista e recebendo um Bolsista ou seja a classe É UM bolsista e TEM UM Bolsista!.

Na verdade, nesse caso, você não deveria receber um bolsista no construtor. De qualquer maneira a meu ver problema não é herança múltipla e sim o problema de classificação e versus generalização! Tanto que na letra c ele diz que pode ser implementado em C++ que permite herança multipla![/quote]

Esqueci de falar, o que você acha que é o problema já que você disse que não é herança múltipla seguindo os princípios de programação OO?

Não vi o contexto das classes que ele colocou, mas, a meu ver, o problema é herança versus composição. Para exemplificar, imagine uma classe Pessoa. Delas herdam as classes PessoaFisica e PessoaJuridica.

Bom agora eu Implemento uma Fornecedor que herda de PessoaJuridica e uma classe cliente que herda PessoaFisica. Tudo funciona bem até que q empresa decide que vai vender também para pessoas juridicas e que pessoas físicas também podem ser fornecedores!

Nesse caso a raiz do problema é que um Cliente NÃO É uma PessoaFisica e um Fornecedor NÃO É uma PessoaJuridica. Na verdade a classe Cliente TEM UM cadastro de PessoaFisica
e o fornecedor TEM UM cadastro de PessoaJuridica.