[RESOLVIDO]Acesso a método abstract como se fosse static

5 respostas
ECO2004

Olá!!

Eu estou com uma dúvida com relação a um acesso do código abaixo.

abstract class Midia {
protected String titulo;
public String getTitulo(){return titulo;}
public void setTitulo(String v){titulo=v;}
public abstract Midia clone();
}
class Video extends Midia{
private String produtora;
private String diretor;
public String getProdutora(){return produtora;}
public void setProdutora(String v){produtora=v;}
public String getDiretor(){return diretor;}
public void setDiretor(String v){diretor=v;}
public Midia clone() {
Video v = new Video();
v.setTitulo(titulo);
v.setProdutora(produtora);
v.setDiretor(diretor);
return v;
}
}
class Jogo extends Midia{
private String fabricante;
private int console;
public String getFabricante(){return fabricante;}
public void setFabricante(String v){fabricante=v;}
public int getConsole(){return console;}
public void setConsole(int v){console=v;}
public Midia clone() {
Jogo j = new Jogo();
j.setTitulo(titulo);
j.setFabricante(fabricante);
j.setConsole(console);
return j;
}
}
class Musical extends Midia{
private String autor;
private String produtora;
public String getAutor(){return autor;}
public void setAutor(String v){autor=v;}
public String getProdutora(){return produtora;}
public void setProdutora(String v){produtora=v;}
public Midia clone() {
Musical m = new Musical();
m.setTitulo(titulo);
m.setAutor(autor);
m.setProdutora(produtora);
return m;
}
}
class Conserto {
private Midia midia;
public Midia getMidia(){return midia;}
public void setMidia(Midia v){midia=v.clone();}
}

Esse é um exemplo simples do uso do padrão de projeto “Protótipo”.
A questão está na linha:

public void setMidia(Midia v){midia=v.clone();}

A classe Concerto tem uma referência para a classe Midia.
Em setMidia, é passado um parâmetro do tipo Midia.
O método clone() é abstrato, e não estático (static). Assim, não daria problema no código abaixo?

midia = v.clone()

Para mim, deu NullPointerException.

5 Respostas

ViniGodoy

NullPointerException é um erro fácil de resolver:

  1. Olhe na StackTrace em que linha o erro ocorreu;
  2. Coloque um breakpoint nessa linha;
  3. Veja qual variável você está acessando está nula.

Por exemplo, nesse caso, o objeto v pode estar nulo.

ECO2004

ViniGodoy:
NullPointerException é um erro fácil de resolver:

  1. Olhe na StackTrace em que linha o erro ocorreu;
  2. Coloque um breakpoint nessa linha;
  3. Veja qual variável você está acessando está nula.

Por exemplo, nesse caso, o objeto v pode estar nulo.

Eu não estou preocupado com o NullPointerException, mas sim com o acesso ao método abstrato.

media = v.clone()

O método clone() é abstrato, e não estático (static). Acesso direto (sem instância) não é somente para métodos estáticos?
Outra coisa: nesse meu caso, não estou acessando a definição do método abstrato em “Midia” ?
Deveria ser permitido eu acessar o método abstrato implementado, e não a sua definição!

Alguém a me explicar o que está acontecendo?

S

Opa,

todas as classes que estendem Midia são Midias, concorda? Isso faz com que você não precise ter um método para cada tipo de mídia, mas sim um único método que é válido para o Video, Jogo e etc.

Quando você for chamar o setMidia, vai passar uma instância de Video, ou Jogo ou whatever que estende Midia.

ViniGodoy

O v.clone() sempre será chamado sobre um tipo concreto de mídia.

Midia m = new Video(); //A mídia é um vídeo
Midia clone = m.clone(); //Chama o método clone() de vídeo.

Só um detalhe, é uma boa prática retornar o tipo da própria classe quando sobrescrever o clone:

class Musical extends Midia{  
    private String autor;  
    private String produtora;  
    public String getAutor(){return autor;}  
    public void setAutor(String v){autor=v;}  
    public String getProdutora(){return produtora;}  
    public void setProdutora(String v){produtora=v;}  

    @Override
    public Musical clone() {  
        Musical m = new Musical();  
        m.setTitulo(titulo);  
        m.setAutor(autor);  
        m.setProdutora(produtora);  
        return m;  
    }  
}
ECO2004
ViniGodoy:
O v.clone() sempre será chamado sobre um tipo concreto de mídia.
Midia m = new Video(); //A mídia é um vídeo
Midia clone = m.clone(); //Chama o método clone() de vídeo.

Só um detalhe, é uma boa prática retornar o tipo da própria classe quando sobrescrever o clone:

class Musical extends Midia{  
    private String autor;  
    private String produtora;  
    public String getAutor(){return autor;}  
    public void setAutor(String v){autor=v;}  
    public String getProdutora(){return produtora;}  
    public void setProdutora(String v){produtora=v;}  

    @Override
    public Musical clone() {  
        Musical m = new Musical();  
        m.setTitulo(titulo);  
        m.setAutor(autor);  
        m.setProdutora(produtora);  
        return m;  
    }  
}

Vlw pela ajuda!

Criado 7 de julho de 2011
Ultima resposta 7 de jul. de 2011
Respostas 5
Participantes 3