Ir para o conteúdo
  • Revista PROGRAMAR: Já está disponível a edição #57 da revista programar. Faz já o download aqui!

Gurzi

Cast de Objectos

Mensagens Recomendadas

Gurzi    2
Gurzi

Venho aqui deixar uma dúvida que me surgiu no Polimorfismo ( cast de objectos).

Ora bem, Imaginem duas classes, Animal e Cão, em que Cão é um extends de Animal e eu na classe Cão tenho varíaveis que não tenho na classe Animal, por exemplo , doençaxpto =  false;

Se eu fizer isto

Cao estupido  = new Cao("true");

Animal teste =  estupido ;

Estou a fazer um cast para a superclasse, mas como Animal não tem a variável da doença o que acontece ao dado ? é perdido  ou juntam-se os métodos e atributos das duas classes ?

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites
Kyu    0
Kyu

como estás a fazer cast para uma classe que não tem os métodos e atributos da classe inicial, estes não serão reconhecidos, no entanto a informação não é perdida pois se voltares a fazer o cast para Cão os métodos e atributos ainda lá estão  :cheesygrin:

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites
Rui Carlos    309
Rui Carlos

não só não se perdem atributos, como se invocares um métodos com a variável 'teste' que esteja definido nas duas classes, o método usado será o da classe 'Cao' (apesar de 'teste' ser da classe 'Animal').

experimenta fazer 'teste.getClass().getName()' e verás que apesar da variável ser do tipo 'Animal' o objecto armazenado é da classe 'Cao'.

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites
Knitter    101
Knitter
(apesar de 'teste' ser da classe 'Animal').

Não vou adiantar muito, a solução já está dita, mas para que não existam confusões.

Uma coisa é a declaração da variável, outra coisa é o tipo da variável em tempo de execução. Neste caso a variável "teste" foi declarada como  sendo do tipo "Animal" mas o seu tipo real, o tipo que determina o comportamento do objecto, apenas é verificado em tempo de execução, e em tempo de execução, neste caso, a variável é do tipo "Cao".

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites
Gurzi    2
Gurzi

Surgiu-me uma nova dúvida

 

**************************************/

class A extends Object{
  public void m(){
    System.out.println("m in class A");
  }//end method m()
}//end class A
//===================================//

class B extends A{
  public void m(){
    System.out.println("m in class B");
  }//end method m()
}//end class B
//===================================//

public class Poly03{
  public static void main(
                        String[] args){
    Object var = new B();
    //Following will compile and run
    ((B)var).m();
    //Following will also compile 
    // and run due to polymorphic
    // behavior.
    ((A)var).m();
}
}

Porque raio o output é sempre "im class b" em vez de ser a A ?

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites
Gurzi    2
Gurzi

Criaste um objecto do tipo classe B e estás a chamar o método dessa classe e não da classe A.

Então mas eu fiz um cast para A

((A)var).m();

e ele mostrou o mesmo metodo de b :s

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites
shumy    17
shumy

Para perceberes isto, terás de entender como funciona internamente o mecanismo de polimorfismo.

O objecto criado B tem um ponteiro para os métodos da classe B, e isso não é alterado com o cast, logo vai apontar sempre para os métodos da classe B. 

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites
Gurzi    2
Gurzi

Então quer dizer que um cast so vai funcionar para métodos que existam noutra classe acima ou a baixo que nao existam na classe de origem porque se não o método chamado é o de origem, neste caso o B , certo ?

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites
shumy    17
shumy

só vaz conseguir chamar métodos que existam para a classe assoiada á instância.

O cast permite que isto seja executado, mesmo quando a variavel está guardada na superclasse.

A utilizade de ter varias instâncias de classes diferentes dentro da superclasse é em geral para permitir o uso de contentores genéricos.

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites
shumy    17
shumy

Não é nada.

Para ficar assente.

O tipo real dos objectos é definido quando estes são criados.

O cão será sempre um cão. Também é um animal, mas não pode deixar de ser cão por causa disso.

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites
Gurzi    2
Gurzi

Sim e a cena dos ponteiros que falas-te ajudou-me imenso.

Não estou a perceber então para quê dos casts visto que um método da superclasse é sempre dado á subclasse..

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites
shumy    17
shumy

A utilidade pode vir no caso:

Pretendes guardar animais numa quinta, essa quinta é um array de animais.

Vas guardar vacas, gatos, cães, tudo num array de animais.

Se queres aceder a um método especifico de um animal, tipo cão tens de fazer o cast.

Para o exemplo que deste, não serve de nada, já que m() existe nas duas classes.

É melhor não entrar para os ponteiros, a não ser que saibas o que são ponteiros para funções.

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites
Gurzi    2
Gurzi

Ok já tinha lido sobre isso, assim fico muito mais esclarecido...

Ou seja, pelo que li, por vezes dá jeito passar um argumento como a maior superclasse neste caso animal, depois se precisar de chamar algo faço um cast...

Obrigado mesmo :D!!!

Já agora uma pergunta offtopic :

Não liguei muito ás enumerations, são muito utilizadas ??

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites
shumy    17
shumy

Enums, em Java não utilizo muito, só mesmo em C++.

Mais uma coisa em relação ao polimorfismo que pode ser enganador. O polimorfismo quando usado nos construtores pode levar a comportamentos estranhos, depende também do compilador. Por isso não é aconselhavel de forma alguma usar funções polimorficas da propria classe nos construtores.

Um exemplo tirado da Net, ligeiramente alterado:

public class Base {
    void m() {
        System.out.println("Base.m: ");
    }
    public Base() {
        System.out.println("Base: inicio construcao");
        m();
        System.out.println("Base: fim construcao");
    }
}

public class Derivada extends Base {
    int valor = 1;
    void m() {
        System.out.println("Derivada.m: " + valor);
    }
    public Derivada(int v) {
        System.out.println("Derivada: inicio construcao");
        valor = v;
        System.out.println("Derivada: fim construcao");
    }

    public static void main(String[] args) {
        new Derivada(10);
    }
}

Isto não se deve fazer.

Experimenta tirar o resultado disto.

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites
Gurzi    2
Gurzi

Porque raio aparece o resultado primeiro da Base ?????

fill(Polygon)

fill(Rectangle)

call it like this:

Polygon polygon = new Rectangle();// not realistic code, just an example

fill(polygon);

Ao fazer o fill/polygon) vai ser chamado o fill do Rectangle ou do Polygon ?

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites
Rui Carlos    309
Rui Carlos

Ao fazer o fill/polygon) vai ser chamado o fill do Rectangle ou do Polygon ?

se a classe 'Rectangle' tiver o método 'fill' implementado é chamado o método da classe 'Rectangle', caso contrário é chamado o da classe 'Polygon' (ou eventualmente de um super-classe de um nível superior).

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites
Gurzi    2
Gurzi

Obrigado  :biggrin:

Vejam isto. ..

Aprendi que por exemplo temos uma classe chamada base e outra derivada, a derivada é filha de base..

Se eu fizer isto

Base xpto = new Derivada();

e depois fizer xpto.ummetodo() o método chamado é o do objecto Derivada mas se eu fizer

System.out.println(xpto.name) o name a ser chamado vai ser do pai , porque ????

Então como consigo chamar atributos da subclasse ?

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites
Rui Carlos    309
Rui Carlos

os atributos da subclasse têm nomes diferentes dos da classe base, não?

se criasses funções 'get' já podias aceder aos atributos das subclasses.

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites
shumy    17
shumy

Mais uma vez, não podemos fazer a minima ideia. Porque não nos dizes onde é definido esse atributo.

Pelo que afirmaste, suponho que seja definido na classe base. E nesse caso o atributo também faz parte da classe derivada.

vendo as coisas desta forma não faz sentido dizer que o atributo chamado vai ser da classe base, já que este pertence ás duas classes.

Para ser mais exacto pertence ás instâncias das classes.

A questão é que, os valores dos atributos estão associados a uma instância, enquanto que o código de uma função está associado a uma classe.

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Crie uma conta ou ligue-se para comentar

Só membros podem comentar

Criar nova conta

Registe para ter uma conta na nossa comunidade. É fácil!

Registar nova conta

Entra

Já tem conta? Inicie sessão aqui.

Entrar Agora


×

Aviso Sobre Cookies

Ao usar este site você aceita os nossos Termos de Uso e Política de Privacidade