3

I am a bit confused about the keyword this in Java, I thought this is referring to the current object. In the below example I have created a class A and a class B that extends A. In the main function when I call the printMyArray function it prints 1 2 3 instead of 4 5 6 7. Is there a way for me to call the printMyArray function and print the array that is initialized in B? So far I can achieve it by having an exact same method in class B as well but I feel it is not the best way to do it.

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};
}
Nix Wang
  • 31
  • 2
  • 1
    *..Is there a way for me to call the printMyArray function and print the array that is initialized in B?..* --> No, because `printMyArray ` exists in A which B is extending. – Am_I_Helpful Jul 23 '17 at 05:24

3 Answers3

2

The code in class A can't access the private parts of class B. So when you write this.numbers in the code of class A, it will refer to the numbers field in class A. When you write this.numbers in the code of class B, it will refer to the numbers field in class B.

Note that fields don't get overridden in the same way that methods do. In your example, an object of class B will carry around both numbers fields. Which one you get depends on which class contains the code that you're running.

This is why it's generally a terrible idea to use the same name for a superclass field and a subclass field.

Dawood ibn Kareem
  • 77,785
  • 15
  • 98
  • 110
2

You define in each class :

private int[] numbers 

And besides private fields are not inherited.
So, referencing numbers inside the A class will always refer to the numbers field declared in the A class.
Same logic for referencing numbers inside the B class that will always refer to the numbers field declared in the B class.

So here printMyArray() will use only the field of the class where this method is declared :

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

That's why, its execution prints always :

1,2,3

To solve your problem, you could introduce a public method getNumbers() that will be the way to retrieve the numbers of each class.
As a public method is overridable, it will now work.

In A, add :

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

Update the printMyArray() method so that is uses getNumbers() and not the numbers field.

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

And override getNumbers() method in B so that is uses its numbers field:

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

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

You could also make numbers a protected field so that it is inherited in B such as :

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

It spares the getNumbers() method.

davidxxx
  • 125,838
  • 23
  • 214
  • 215
0

This is because the definition of printMyArray() method exists in class A. If you want to print objects of class B, then you'll have to override it in class 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]);
        }
    }
}

Now you'll get output as : 4 5 6 7

Raman Sahasi
  • 30,180
  • 9
  • 58
  • 71