Polimorfismo

jorijo

Power Member
Boas!

Tenho uma classe base Veiculo e duas classes derivadas Veiculo_frigorifico e Veiculo_lona.

A classe Veiculo_lona tem os mesmos atributos que a classe base mas Veiculo_frigorifico tem a mais o atributo desp_manutencao_fri.

O que eu quero saber é onde devo declarar o metodo de acesso ao atributo desp_manutencao_fri uma vez que apenas pertence à classe Veiculo_frigorifico...

obrigado
 
Usa uma interface onde tens a assinatura desse método, e depois implementas essa interface na classe Veiculo_frigorifico, implementando o método de acesso.
 
Eu tenho um software onde tenho uma class base com alguns metodos, e tenho 5 ou 6 class que herdam dessa mesma e cada uma delas contem os metodos da base.

Até aqui é o mesmo que tens.

Depois em cada uma das classes, tenho metodos diferentes. e declaro esse mesmo metodos na class que esta a usa-los.

Exemplo:

Class Base
- ID
- Nome
- Idade
- Sexo

Class 1:
- Contem os acima
- declaro tambem o Contribuiente e Bi

Class 2:
- Contem os da class base
- Declaro o Bilhete de autocarro e carta de conducao.

Resultado final

Class1
- ID
- Nome
- Idade
- Sexo
- Contribuiente
- BI

Class2
- ID
- Nome
- Idade
- Sexo
- Billhete de autocarro
- Carta de condução.

Espero que assim comprendas.
 
Eu tenho um software onde tenho uma class base com alguns metodos, e tenho 5 ou 6 class que herdam dessa mesma e cada uma delas contem os metodos da base.

Até aqui é o mesmo que tens.

Depois em cada uma das classes, tenho metodos diferentes. e declaro esse mesmo metodos na class que esta a usa-los.

Exemplo:

Class Base
- ID
- Nome
- Idade
- Sexo

Class 1:
- Contem os acima
- declaro tambem o Contribuiente e Bi

Class 2:
- Contem os da class base
- Declaro o Bilhete de autocarro e carta de conducao.

Resultado final

Class1
- ID
- Nome
- Idade
- Sexo
- Contribuiente
- BI

Class2
- ID
- Nome
- Idade
- Sexo
- Billhete de autocarro
- Carta de condução.

Espero que assim comprendas.
Sim, mas ele quer usar polimorfismo, ou seja, pegando nas tuas classes, o que ele quer é fazer isto:
Código:
Base b = new 1();
Ao tentares invocar qualquer método que apenas esteja definido na classe 1, vai ocorrer um erro, porque apesar do tipo dinâmico da variável b ser 1, o seu tipo estático é Base, e nessa classe não está definido o tal método invocado.
 
Usa uma interface onde tens a assinatura desse método, e depois implementas essa interface na classe Veiculo_frigorifico, implementando o método de acesso.
Peço desculpa, mas apresentei esta solução e ela está errada, não funciona.
A solução para o teu caso passa por, sempre que fores invocar o método que apenas existe na subclasse, fazeres o casting da variável sobre a qual chamas o método, para o tipo da subclasse. Ou seja:
Código:
Veiculo v = new Veiculo_frigorifico();
if (v instanceOf Veiculo_frigorifico)
... = ((Veiculo_frigorifico)v).getDespManutencaoFri();
 
Eu começo por fazer duas correcções básicas aos nomes propostos para as classes e para o método: o underscore só se usa em variáveis "constantes" em Java. O nome da classe deve ter a primeira letra de cada palavra em maiúscula, sem underscores a separar (o que se designa por CamelCase). Ficaria então assim: VeiculoFrigorifico e VeiculoLona.

Relativamente ao nome do atributo, não se percebe muito bem o que é. Eu presumo que seja despesa do veículo frigorífico. Nesse caso eu sugiro que não se poupem letras (não se paga mais por isso :)). Os underscores ficam também de fora e a letra da primeira palavra fica em minúscula. Ficaria portanto: despesaManutencaoFrigorifico (como este atributo fica na classe VeiculoFrigorifico, eu até sugiro que se chame apenas despesaManutencao).

Agora coloca-se uma questão pertinente relativamente a este atributo: é só o VeiculoFrigorifico que tem despesa de manutenção? O VeiculoLona não tem (pode assumir-se que tem despesa 0)?

Então eu sugiro o seguinte: na classe Veiculo declaras o método getDespesaManutencao(). Podes até declará-lo como abstracto (e consequentemente Veiculo passa também a abstracta), ou então devolves simplesmente o valor 0.
Na classe VeiculoFrigorifico fazes o override ao método para devolver o conteúdo da variável despesaManutencao (que estará declarada apenas na classe VeiculoFrigorifico).

A sugestão do Baderous relativamente ao instanceof é muito perigosa. Quando se usa extensivamente este operador é sinal de que algo está mal na modelação do problema. A solução que te propus evita a utilização do instanceof assumindo uma característica em comum a todos os veículos (despesaManutencao), ainda que alguns veículos possam ter essa característica a zero. Isto é que é o polimorfismo (numa das suas formas, já que para além do override também se pode falar em overload de métodos).
 
Agora coloca-se uma questão pertinente relativamente a este atributo: é só o VeiculoFrigorifico que tem despesa de manutenção? O VeiculoLona não tem (pode assumir-se que tem despesa 0)?

Então eu sugiro o seguinte: na classe Veiculo declaras o método getDespesaManutencao(). Podes até declará-lo como abstracto (e consequentemente Veiculo passa também a abstracta), ou então devolves simplesmente o valor 0.
Na classe VeiculoFrigorifico fazes o override ao método para devolver o conteúdo da variável despesaManutencao (que estará declarada apenas na classe VeiculoFrigorifico).

A sugestão do Baderous relativamente ao instanceof é muito perigosa. Quando se usa extensivamente este operador é sinal de que algo está mal na modelação do problema. A solução que te propus evita a utilização do instanceof assumindo uma característica em comum a todos os veículos (despesaManutencao), ainda que alguns veículos possam ter essa característica a zero. Isto é que é o polimorfismo (numa das suas formas, já que para além do override também se pode falar em overload de métodos).
Eu também pensei nessa solução, quer utilizando o método como abstracto, quer como concreto devolvendo o valor 0, sendo redefinido apenas na classe Veiculo_frigorifico. Do ponto de vista funcional isso está correcto e permite o uso de polimorfismo. Do ponto de vista de concepção (não sei se é o nome correcto), não faz sentido que um veículo que não seja frigorífico tenha acesso a um método que devolve as despesas de manutenção de um frigorífico. Foi apenas e só por essa questão que optei pelo instanceOf, aliás, da experiência que tenho, é a única situação em que utilizo essa operação.
 
A solução passa por reinterpretar o problema e recorrer ao polimorfismo para resolver o problema pendente. Neste caso considera-se que todos os veículos têm despesa de manutenção, ainda que apenas alguns tenham esse valor > 0, em vez de considerar a despesa específica de um veículo frigorífico.

Se ele quer trabalhar com referências do tipo Veiculo com instâncias e VeiculoFrigorifico, o melhor é mesmo garantir que todos os veículos conseguem devolver uma despesa de manutenção.
 
Back
Topo