2017-07-23 6 views
3

Je suis un peu confus sur le mot-clé ce en Java, je pensais ce fait référence à l'objet actuel. Dans l'exemple ci-dessous, j'ai créé une classe A et une classe B qui étend A. Dans la fonction principale lorsque j'appelle la fonction printMyArray, elle imprime 1 2 3 au lieu de 4 5 6 7. Y at-il un moyen d'appeler? la fonction printMyArray et imprimer la matrice qui est initialisée dans B? Jusqu'à présent, je peux y arriver en ayant exactement la même méthode en classe B, mais je pense que ce n'est pas la meilleure façon de le faire.Java - la portée du mot-clé ceci lors de l'annulation des méthodes

public class Main { 

    public static void main(String[] args) { 

     B b1 = new B(); 
     b1.printMyArray(); 
    } 
} 

class A { 
    private int[] numbers = {1,2,3}; 

    public void printMyArray() { 
     for(int i =0; i < this.numbers.length; i++){ 
      System.out.println(numbers[i]); 
     } 
    } 
} 

class B extends A { 
    private int[] numbers = {4,5,6,7}; 
} 
+1

* .. Est-il possible d'appeler la fonction printMyArray et d'imprimer le tableau initialisé dans B? .. * -> Non, car 'printMyArray' existe dans A que B étend. –

Répondre

0

En effet, la définition de printMyArray() méthode existe en classe A. Si vous souhaitez imprimer des objets de la classe B, alors vous devrez le remplacer dans la classe B.

... 
class B extends A { 
    public int[] numbers = {4,5,6,7}; 

    public void printMyArray() { 
     for(int i =0; i < this.numbers.length; i++){ 
      System.out.println(numbers[i]); 
     } 
    } 
} 

maintenant vous obtiendrez la sortie sous la forme: 4 5 6 7

2

Le code de la classe A ne peut pas accéder aux parties privées de la classe B. Ainsi, lorsque vous écrivez this.numbers dans le code de la classe A, il se référera au champ numbers dans la classe A. Lorsque vous écrivez this.numbers dans le code de la classe B, il se référera au champ numbers dans la classe B.

Notez que les champs ne sont pas remplacés de la même manière que les méthodes. Dans votre exemple, un objet de la classe B transportera les deux champs numbers. Lequel vous obtenez dépend de la classe qui contient le code que vous utilisez.

C'est pourquoi c'est généralement une mauvaise idée d'utiliser le même nom pour un champ de super-classe et un champ de sous-classe.

2

vous définissez dans chaque classe:

private int[] numbers 

Et en plus private champs ne sont pas hérités.
Ainsi, en référençant numbers à l'intérieur de la classe A, vous faites toujours référence au champ numbers déclaré dans la classe A.
Même logique pour faire référence à numbers à l'intérieur de la classe B qui fera toujours référence au champ numbers déclaré dans la classe B.

donc ici printMyArray() utilisera uniquement le champ de la classe où cette méthode est déclarée:

public void printMyArray() { 
     for (int i = 0; i < this.numbers.length; i++) { 
     System.out.println(numbers[i]); 
     } 
    } 

Voilà pourquoi, ses impressions d'exécution toujours:

1,2,3 

Pour résoudre votre problème, vous pouvez introduire une méthode publique getNumbers() qui sera le moyen de récupérer le numbers de chaque classe.
Comme une méthode publique est substituable, cela va maintenant fonctionner.

En A, ajouter:

public int[] getNumbers() { 
    return numbers; 
} 

Mise à jour de la méthode printMyArray() afin qu'il utilise des getNumbers() et non le champ numbers.

public void printMyArray() { 
    for(int number : getNumbers()){ 
     System.out.println(number); 
    } 
} 

Et remplacer la méthode getNumbers() dans B de sorte qu'il utilise des sonnumbers terrain:

private int[] numbers = {4,5,6,7}; 

public int[] getNumbers() { 
    return numbers; 
} 

Vous pouvez aussi faire numbers un champ protected afin qu'il soit hérité dans B tels que:

protected int[] numbers = {1,2,3}; 

Il ménage la méthode getNumbers().

0

Peu importe ce que vous faites, vous ne pouvez pas accéder à la variable privée (sans réflexion). Si vous avez besoin de sa valeur, invoquez le getter de la superclasse dans votre getter, pour obtenir la valeur, puis manipulez-la comme vous voulez. Vous pouvez appeler la méthode de la superclasse en faisant

super.getValue(); 

dans votre implémentation getValue.

Compte tenu de votre mise à jour

public class B extends A { 
    public String getValue() { 
     String superS = super.getValue(); 
     return superS + "bar"; 
    } 
} 
  1. Im en utilisant étend que vous ne le faites pas. extends est pour étendre une classe , implémente est pour implémenter une interface.
  2. Je ne fais pas d'ombre s. Je laisse ça dans la super classe. Je viens d'utiliser le super getValue en conjonction avec ce que la décoration spécifié.