Solucionado (ver solução)
Solucionado
(ver solução)
1
resposta

Dúvida no Ex. 8 da Aula 3 - Diferencie tipo de uma referência e tipo de um objeto

Olá pessoal.

package financeiro;
    public class ContaFinanceira extends modelo.Conta {
        public void fecha() {
            System.out.println("fechando financeiro");
        }
    }

    package modelo;
    public class Conta {
        public void fecha() {
            System.out.println("fechando conta normal");
        }
    }

    package codigo;
    import financeiro.*;
    import modelo.*;
    class A {
        public static void main(String[] args) {
            Conta c = new ContaFinanceira();
            c.fecha();
        }
    }

Sobre esta questão, gostaria de entender melhor porque na instância de uma ContaFinanceira, com sua referência do tipo Conta chama o método da classe ContaFinanceira.

Não entendi claramente pois é explicado neste tópico que o compilador conhece as variáveis de classe e métodos do tipo da variável de referência e não do tipo da instância ( new Bla(); ).

Fiz um teste com o mais clássico exemplo de polimorfismo:

List l = new ArrayList();

Quanto tentei acessar o método trimToSize() que pertence a classe ArrayList, não pude acessá-lo, pois o tipo da referência é List, interface na qual não possui este método. Mas quando mudo seu tipo para ArrayList consigo enchergá-lo.

Porém neste caso, mesmo o tipo da variável não sendo Conta, é chamado o método fecha() da classe ContaFinanceira(), porquê?

Acho que estou deixando passar alguma coisa, então vão me perdoando de ante-mão ;)

Grato.

1 resposta
solução!

Olá, confesso que fiquei um pouco confuso quando vi a pergunta porque já me confundi diversas vezes com isso. O comportamento das suas classes está correto (mais exemplos: http://docs.oracle.com/javase/tutorial/java/IandI/polymorphism.html)

Tentando explicar o que eu entendi sem falar besteira e deixar tudo mais confuso: Acho que o comportamento "estranho" que você percebeu tem a ver com a sobreescrita (override) dos métodos. Quando você declara a variável do tipo Conta e instancia uma ContaFinanceira, ao chamar um método de Conta que foi sobreescrito em ContaFinanceira a jvm executa o método da ContaFinanceira. Mas Se tentar executar um método da ContaFinanceira que não tenha sido herdado de Conta o erro de compilação aparece. e.g.:

public class ContaFinanceira extends Conta {
    @Override
    public void fecha() {
        System.out.println("fechando financeiro");
    }
    public void abre(){
        System.out.println("abre");
    }
}

Conta c = new ContaFinanceira();
c.abre();
Exception in thread "main" java.lang.RuntimeException: Uncompilable source code - Erroneous sym type: inheritest.Conta.abre
    at inheritest.test.main(test.java:27)