• Revista PROGRAMAR: Já está disponível a edição #53 da revista programar. Faz já o download aqui!

Gurzi

Cast de Objectos

24 mensagens neste tópico

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 ?

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

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:

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

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'.

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites
(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".

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

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 ?

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

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

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

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

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Foi explicado pelo Rui Carlos ai atras.

A instância criada foi de B. Será sempre um B. 

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

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. 

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

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 ?

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

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.

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

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.

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

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..

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

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.

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

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 ??

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

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.

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

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 ?

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

O pessoal não é bruxo. Não sei que função é essa fill. Onde está a definição?

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

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).

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

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 ?

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

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.

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

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.

0

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