public class Fisherman
{
public static void main(String[] args) {
Fish f = new Walleye();
Walleye w = new Walleye();
Bluegill b = new Bluegill();
if(f instanceof Perch) System.out.print("f-p ");
if(w instanceof Fish) System.out.print("w-f ");
if(b instanceof Fish) System.out.print("b-f ");
}
}[/code]
Pra mim era para dar erro na linha 20, já que é impossível b ser uma instância de Fish. Alguém pode me explicar porque não gera erro de compilação na linha 20?
O instanceof serve só para perguntar se o objeto é instancia de uma determinada classe. Logo não teria porque da erro, simplesmente o print da linha 20 não será impresso.
Whatever w = new Whatever();
if(w instanceof Object) ; //ok, compila normal ate aqui
if(w instanceof String) ;//nao compila! O compilador detecta que w não pode ser filha/pai de String sobre NENHUMA HIPOTESE!
}
}
[/code]
Por que entao no meu primeiro exemplo o compilador tambem nao detecta?
porq no primeiro exemplo vc está utilizando interfaces…
quando vc compara com uma interface não dará erro de compilação porq a classe poderá estar implementando a interface de forma indireta…
[quote=vmsb11]porq no primeiro exemplo vc está utilizando interfaces…
quando vc compara com uma interface não dará erro de compilação porq a classe poderá estar implementando a interface de forma indireta…[/quote]
Não é bem isso, isso aqui também não compila:
String o = new String();
if (o instanceof Fish) System.out.println();
A resposta é simples e você já disse, não compila por que String em nenhum hipótese pode ser um Fish, afinal ele é final…
Não tem como mudar a árvore, mude o Bluegill para final também que você vai ter o erro de compilação.
O exemplo abaixo é válido e o instance of retorna true.
public final class BluegillChild extends Bluegill implements Fish {}
public class Fisherman {
public static void main(String[] args) {
Bluegill b = new BluegillChild();
if (b instanceof Fish) System.out.print("b-f ");
}
}
Agora sim, através de polimorfismo podemos dizer que Bluegill é sim um Fish.
andeb, quer dizer que só ocorre erros de compilação no instanceof quando vc está fazendo qualquerReferenciaDeQualquerClasseSejaEstaFinalOuNao instanceof AlgumaCoisaFinalAqui ou algumacoisafinalaqui instanceof QualquerClasseOuInterfaceSejaElaFinalOuNao ??? É isso? :shock:
Nesse caso, a recíproca é verdadeira hehe
Não importa em qual lado vai estar o final, o compilador vai acusa como erro quando não for possível, em hipótese nenhuma, que a condição seja verdadeira. Quando uma classe não é final, ela pode ser extentida e/ou implementado por outra que faça a condição ser verdadeira.
TipoQualquer t = ...
if (t instanceof MinhaClasse) {
//
}
Só vai dar erro de compilação quando o tipo da variável t não for “pai” (ou “avô”, ou “bisavô”…) de MinhaClasse, porque aí, é obvio que não há a possiblidade de ser verdadeiro. Ou melhor dizendo: é erro quando as classes TipoQualquer e MinhaClasse não são da mesma árvore da hierarquia de classes.
Agora, com interfaces, a coisa muda de figura, porque não existe qualquer relação de hierarquia entre classe e interface. Suponha a seguinte situação:
TipoQualquer t = ...
if (t instanceof MinhaInterface) {
//
}
Talvez TipoQualquer não implemente MinhaInterface. Mas quem garante que filhos de TipoQualquer (que podem ser atribuídos à variável t) não resolva implementar essa interface? Ninguém! Por isso que o compilador não pode fazer nada! No primeiro exemplo ali de cima, não tem como um filho de TipoQualquer herdar de MinhaClasse, não existe herança múltipla!
Leonardo3001, por esse seu racioncínio, não tem como afirmar que sempre que você estiver fazendo x instanceof InterfaceQualquerAqui e x se referir à uma classe não final, não iremos ter um erro de compilação?