Java - Dúvida: Herança, Polimorfismo

6 respostas
V

Primeiramente olá a todos, meu nome é Victor e esse é o meu primeiro post.

Minha dúvida é a seguinte: eu quero que uma classe "pai" passe variáveis obrigatórias diretamente para a classe "filho". Como assim? Exemplo:
public class Funcionario {
	//Variáveis que serão passadas para a classe "filho"
	private float salario;
	private int cargaHoraria;
}
Eu gostaria que essas variáveis fossem passadas para essa outra classe como forma obrigatória e visivel:
public class Professor extends Funcionario{

}
No caso assim:
public class Professor extends Funcionario{
	//Variáveis que foram passadas obrigatoriamente para essa classe
	private float salario;
	private int cargaHoraria;
}

Algo parecido com os métodos obrigatórios que algumas classes passam só que em forma de variáveis.

Espero que tenham entendido, muito obrigado.
Obs.: o "extends" foi só um exemplo.

6 Respostas

javahunter

Olha amigo com variáveis eu não sei se dá pra fazer isso.

Mas se você usar os métodos getters e setters ou encapsulamento com o modificador abstract.

Estará obrigando a classe filho usar esses métodos.
public abstract class Funcionario {  
    protected float salario;  
    protected int cargaHoraria;

    public abstract void setSalario(float salario);

    public abstract void setCargaHoraria(int cargaHoraria);

    public abstract float getSalario();

    public abstract int getCargaHoraria();
}
public class Professor extends Funcionario{  
  // Agora será necessário implementar todos os métodos da classe Funcionario e assim tem que usar todas as variáveis.
  public void setSalario(float salario) {
       this.salario = salario;
    }

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

    public float getSalario() {
       return salario;
    }

    public int getCargaHoraria() {
       return cargaHoraria;
    }
}
V

Obrigado, javahunter!
Eu fiz de outra forma:
Criei uma interface -> Para obrigar a classe a ter os métodos.
Criei uma classe -> Para aplicação dos métodos, para que depois eu possa gerar a herança.
Criei a classe "professor" -> Para teste de polimorfismo.

Interface
public interface Trabalhador {
	public float getSalario();
	public void setSalario(float salario);
	public int getCargaHoraria(); //Horas
	public void setCargaHoraria(int cargaHoraria);
}
Class com a interface
public class Funcionario implements Trabalhador {
	protected float salario;
	protected int cargaHoraria;
	
	@Override
	public int getCargaHoraria() {
		return cargaHoraria;
	}
	@Override
	public void setCargaHoraria(int cargaHoraria) {
		this.cargaHoraria = cargaHoraria;
	}
	@Override
	public float getSalario() {
		return salario;
	}
	@Override
	public void setSalario(float salario) {
		this.salario = salario;
	}
	
}
Class test
public class Professor extends Funcionario{
	int valorHoraAula;
	//Poliformismo
	public float getSalario() {
		salario = valorHoraAula * cargaHoraria;
		return salario;
	}
}

XD

Rodrigo_Sasaki

Sua solução foi bem interessante, mas só pra informação, é possível uma subclasse herdar atributos também, só que não atributos privados.

Quando você diz que um atributo é privado, somente aquela classe terá acesso a ela, então qualquer um que estenda a essa classe sequer saberá que ele existe, agora com modificadores de visibilidade diferentes isso é possível, veja:
public abstract class Funcionario {  
    //Variáveis que serão passadas para a classe "filho"  
    protected float salario;  
    protected int cargaHoraria;  
}
public class Professor extends Funcionario{
	
	public int getCargaHoraria(){
		return cargaHoraria;
	}
	
}
public class Teste{

    public static void main(String[] args){
        Professor professor = new Professor();
        System.out.println(professor.getCargaHoraria());
    }

}
S

Importante frisar que métodos abstratos não possuem corpo, portanto creio que a indicação do javahunter fica inviável:

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

Deveria ser dessa forma:

...
public abstract void setSalario(float salario);
...

E ainda segundo as boas práticas, para cada classe abstrata devemos declarar ao menos um método abstrato, já que o papel da classe abstrata é não ser instanciável (usar new) e promover um mesmo comportamento para seus filhos (parêmetros e tipo de retorno) mas com implementações diferentes por parte deles. Como exemplo segue algumas classes usando abstract:

public abstract Conta {
   protected double saldo; // filhos de conta terão disponível o atributo saldo
   public abstract double getSaldo(); // delega para seus filhos implementarem o corpo do método
}

public class ContaCorrente extends Conta {
  private double limite;
  public double getSaldo() {
     return saldo + limite;
  }
}

public class ContaPoupanca extends Conta {
   public double getSaldo() {
      return saldo;
   }
}

Por favor não se prendam aos cálculos que mostrei aqui, (sou péssimo em matmática financeira, rsrsrs), mas vejam a versatilidade que ganhamos ao usar uma classe abstrata delegando regras aos seus filhos, afinal não precisamos instanciar a classe Conta, ela será utilizada única e exclusivamente em função das classes ContaCorrente e ContaPoupanca.

javahunter

solidsnake:
Importante frisar que métodos abstratos não possuem corpo, portanto creio que a indicação do javahunter fica inviável:

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

Deveria ser dessa forma:

...
public abstract void setSalario(float salario);
...

E ainda segundo as boas práticas, para cada classe abstrata devemos declarar ao menos um método abstrato, já que o papel da classe abstrata é não ser instanciável (usar new) e promover um mesmo comportamento para seus filhos (parêmetros e tipo de retorno) mas com implementações diferentes por parte deles. Como exemplo segue algumas classes usando abstract:

public abstract Conta {
   protected double saldo; // filhos de conta terão disponível o atributo saldo
   public abstract double getSaldo(); // delega para seus filhos implementarem o corpo do método
}

public class ContaCorrente extends Conta {
  private double limite;
  public double getSaldo() {
     return saldo + limite;
  }
}

public class ContaPoupanca extends Conta {
   public double getSaldo() {
      return saldo;
   }
}

Por favor não se prendam aos cálculos que mostrei aqui, (sou péssimo em matmática financeira, rsrsrs), mas vejam a versatilidade que ganhamos ao usar uma classe abstrata delegando regras aos seus filhos, afinal não precisamos instanciar a classe Conta, ela será utilizada única e exclusivamente em função das classes ContaCorrente e ContaPoupanca.


Hehehehehe rrsrsrsrsrs

esqueci esse detalhe, já esta corrigido.

V

Valeu, galera. Os meus objetivos foram atendidos de ambas as formas.

PessoaFisica.java
public abstract class PessoaFisica {
	protected String nome;
	protected String CPF;
	
	public abstract String getNome();
	public abstract void setNome(String nome);
	public abstract String getCPF();
	public abstract void setCPF(String CPF);
}
Funcionario.java
public abstract class Funcionario extends PessoaFisica{
	protected float salario;
	protected int cargaHoraria;
	
	public abstract float getSalario();
	public abstract void  setSalario(float salario);
	public abstract int   getCargaHoraria();
	public abstract void  setCargaHoraria(int cargaHoraria);
}
Professor.java
public class Professor extends Funcionario{
	private float valorHoraAula;
	
	@Override
	public float getSalario() {
		this.salario = cargaHoraria * valorHoraAula;
		return salario;
	}

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

	@Override
	public int getCargaHoraria() {
		return cargaHoraria;
	}

	@Override
	public void setCargaHoraria(int cargaHoraria) {
		this.cargaHoraria = cargaHoraria;
	}

	@Override
	public String getNome() {
		return nome;
	}

	@Override
	public void setNome(String nome) {
		this.nome = nome;
	}

	@Override
	public String getCPF() {
		return CPF;
	}

	@Override
	public void setCPF(String CPF) {
		this.CPF = CPF;
	}

	public float getValorHoraAula() {
		return valorHoraAula;
	}

	public void setValorHoraAula(float valorHoraAula) {
		this.valorHoraAula = valorHoraAula;
	}

}

Acho que está tudo certo, estou no trabalho usando o notebook daqui. Depois dou uma revisada! Valeu galera! :D

Criado 1 de julho de 2013
Ultima resposta 2 de jul. de 2013
Respostas 6
Participantes 4