Pergunta

A seguir está uma parte do meu código para um projeto:

public class Body extends Point{
    public double x, y, mass;

    public Body() {
        x = y = mass = 0;
    }

    public Body(double x, double y, double mass) {
        this.mass = mass;
        this.x = x;
        this.y = y;
    }
}

public class Point {
    public double x;
    public double y;

    public Point(double x, double y) {
        this.x = x;
        this.y = y;
    }
}

Eu rapidamente percebi que fazer isso criaria dois variáveis ​​​​dentro da classe Body chamadas x e duas outras variáveis ​​​​em Body chamadas y.Como isso é possível e por que diabos o Java permite isso?

Presumo que este seja o código correto da classe Body:

public class Body extends Point{
    public double mass;

    public Body() {
        super();
        mass = 0;
    }

    public Body(double x, double y, double mass) {
        super(x,y);
        this.mass = mass;
    }
}

Obrigado pelo seu tempo

Foi útil?

Solução

De certa forma, você está substituindo os campos da superclasse.Mas é muito mais fácil fazer isso acidentalmente porque não há sobrecarga de campos (você só tem uma variável com um determinado nome, o tipo não importa).Isso é conhecido como 'ocultação' ou 'sombreamento' de variável.Então, você está correto, você terá dois campos com o mesmo nome.

Seu segundo exemplo está correto.Eles são herdados da superclasse e, como não são declarados privados, são visíveis para a subclasse.Geralmente é uma má prática referir-se diretamente aos campos de uma superclasse e, a menos que haja um bom motivo, eles devem ser declarados privados.Seu exemplo de invocação do superconstrutor é a melhor abordagem.

Além disso, se você ocultar um campo com outro com o mesmo nome, ainda poderá referir-se a eles como super.x, super.y, vs.this.x, this.y, você deve evitar esta situação se possível.

Outras dicas

Sim, você terá duas variáveis, uma ocultando a outra.Faz sentido permitir isso por dois motivos:

  1. Suponha que você tenha uma classe base Base e uma classe derivada Derived qual o autor de Base não tem ideia sobre.Caso o autor de Base nunca será possível adicionar nenhum campo, só porque uma classe derivada poder compartilhar os campos?Ou deveria Derived pare de compilar quando a mudança para Base na verdade não afeta a correção?
  2. Seus campos quase sempre devem ser privados, e nesse ponto não importa se os nomes estão duplicados ou não - nenhum dos "lados" saberá sobre as variáveis ​​do outro.

Além do que outros disseram:É Body a Point?Não, Body tem uma propriedade de posição do tipo Point.Então Body provavelmente não deveria estender Point.Se você se livrar da herança (de implementação), você se livrará de muitos problemas.Isso e usar private (não protected!) e final liberalmente.

Rapidamente percebi que fazer isso criaria duas variáveis ​​dentro da classe Body chamadas x e duas outras variáveis ​​em Body chamadas y.Como isso é possível e por que diabos o Java permite isso?

Na verdade não, você não está criando duas variáveis ​​com o mesmo nome, obviamente um compilador não deveria e não permitiria isso.

O que você são fazer é sombrear as variáveis ​​existentes definidas como x e y, o que significa que Body.x e Body.y estão essencialmente sobrepondo os nomes de Point.x e Point.y, tornando as duas últimas variáveis ​​completamente inacessíveis da classe Body (link para a definição de "sombreamento" da Especificação da Linguagem Java).

O sombreamento de nomes geralmente é considerado uma prática ruim e uma causa de bugs, e se você ativar os avisos do compilador javac, o compilador irá avisá-lo respeitosamente sobre isso.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top