Razões por trás do comportamento relacionado ao polimorfismo em java

5

Eu li esse código em algum lugar

class Foo {
    public int a;
    public Foo() {
        a = 3;
    }
    public void addFive() {
        a += 5;
    }
    public int getA() {
        System.out.println("we are here in base class!");
        return  a;
    }
}

public class Polymorphism extends Foo{
   public int a;
   public Poylmorphism() {
       a = 5;
   }
   public void addFive() {
       System.out.println("we are here !" + a);
       a += 5;
   }

   public int getA() {
        System.out.println("we are here in sub class!");
        return  a;
    }

    public static void main(String [] main) {
        Foo f = new Polymorphism();
        f.addFive();
        System.out.println(f.getA()); // SOP 1
        System.out.println(f.a);      // SOP 2
    }
}

Para o SOP1, obtemos a resposta 10 e, para o SOP2, obtemos a resposta 3. A razão para isso é que não é possível substituir as variáveis, enquanto você pode fazer isso para os métodos. Isso acontece porque o tipo da variável de referência é verificado quando uma variável é acessada e o tipo do objeto é verificado quando um método é acessado. Mas eu estou pensando, porque é assim? Alguém pode me explicar qual é a razão para esse comportamento

    
por Shades88 16.09.2012 / 14:16
fonte

2 respostas

4

Sua referência é do tipo Foo; não sabe o tipo de objeto a que se refere.

Mesmo com isso, a herança quebra o encapsulamento; permitindo que os campos de instância sejam substituídos também, o encapsulamento seria quebrado ainda mais. Talvez na sua subclasse você esteja chamando um método da superclasse relacionado ao estado do campo de instância a. A implementação da superclasse 'é baseada em sua própria a (ela não pode presumir que uma superclasse existirá e irá sobrescrevê-la) e terá um comportamento muito caótico se você a alterar sobrescrevendo-a.

Além disso, a instância de herança de campo não deve ser permitida, pois os campos de instância devem ser privados.

    
por 16.09.2012 / 14:43
fonte
1

This happens because type of the reference variable is checked when a variable is accessed and type of the object is checked when a method is accessed. But I am wondering, just why is it that way? Can anyone explain me what is the reason for this behaviour

Não é um problema de tipo, é um problema vinculativo.

  • A expressão f.a liga estaticamente ao campo de acordo com o tipo declarado da variável f porque os campos não podem ser substituídos. E a razão pela qual eles não podem ser substituídos é que isso poderia quebrar a substituibilidade (para campos não privados) e quebrar métodos declarados no supertipo que usam o campo.

  • A chamada f.getA() liga dinamicamente ao método no objeto real para implementar o polimorfismo dinâmico e para evitar que os chamadores quebrem a abstração chamando erroneamente um método que tinha foi substituído.

Em suma, se o método de ligação fosse diferente em ambos os casos, o resultado líquido seria uma linguagem menos expressiva com problemas na manutenção de limites de abstração.

A maioria, senão todas, as linguagens OO estaticamente tipadas funcionam dessa maneira. (Se alguém souber de exemplos de contador que também são estaticamente digitados, por favor, comente.)

    
por 18.09.2012 / 03:47
fonte