Avoir 2 variables du même nom dans une classe qui étend une autre classe en Java

Voici une partie de mon code pour un projet:

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; } } 

J’ai vite compris que cela créerait deux variables dans la classe Body appelées x et deux autres variables dans Body appelées y. Comment est-ce possible, et pourquoi Java le permet-il?

Je suppose que c’est le code correct de la 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; } } 

Merci pour votre temps

En un sens, vous écrasez les champs de la super classe. Mais il est beaucoup plus facile de le faire accidentellement car il n’ya pas de surcharge des champs (vous n’avez qu’une variable d’un nom donné, peu importe le type). Ceci est appelé variable “masquage” ou “observation”. Donc, vous avez raison, vous allez vous retrouver avec deux champs portant le même nom.

Votre deuxième exemple est correct. Ils sont hérités de la super-classe et, comme ils ne sont pas déclarés privés, ils sont visibles par la sous-classe. C’est généralement une mauvaise pratique de se référer directement aux champs d’une super-classe, et à moins d’une raison valable, elle devrait être déclarée privée. Votre exemple d’invocation du super constructeur est la meilleure approche.

En outre, si vous masquez un champ avec un autre du même nom, vous pouvez toujours vous y référer en tant que super.x, super.y, vs this.x, this.y, vous devriez éviter cette situation dans la mesure du possible.

Oui, vous aurez deux variables, l’une cachant l’autre. Il est logique de le permettre pour deux raisons:

  1. Supposons que vous ayez une classe de base Base et une classe dérivée Derived dont l’auteur de Base n’a aucune idée. L’auteur de Base ne devrait-il jamais pouvoir append aucun champ, simplement parce qu’une classe dérivée pourrait partager les champs? Ou Derived doit-il cesser de comstackr lorsque le changement de Base n’affecte pas l’exactitude?
  2. Vos champs doivent presque toujours être privés, à quel point le fait que les noms soient dupliqués ou non importe peu – aucun des “camps” ne connaîtra les variables de l’autre.

Suite à ce que d’autres ont dit: Body is a Point ? Non, Body a une propriété de position de type Point . Donc, Body ne devrait probablement pas étendre Point . Si vous vous débarrassez de l’inheritance (de l’implémentation), vous vous débarrasserez de beaucoup de problèmes. Cela et utiliser private (non protected !) Et final libéralement.

J’ai vite compris que cela créerait deux variables dans la classe Body appelées x et deux autres variables dans Body appelées y. Comment est-ce possible, et pourquoi Java le permet-il?

En fait non, vous ne créez pas deux variables avec le même nom, évidemment, un compilateur ne devrait pas et ne permettrait pas cela.

Ce que vous faites, c’est masquer les variables existantes définies comme x et y , ce qui signifie que Body.x et Body.y chevauchent essentiellement les noms de Point.x et de Point.y, rendant les deux dernières variables complètement inaccessibles à partir de la classe Body ( lien vers la définition de “shadowing” dans les spécifications du langage Java ).

Le masquage de nom est généralement perçu comme une mauvaise pratique et une cause de bogues, et si vous affichez les avertissements du compilateur javac, le compilateur vous en avertira consciencieusement.