1
class Machine {
    int info1 = 7;      
    public void show(){
        System.out.println(info1);
    }
}

class Camera extends Machine {
     int info1 = 13;
}

public class Application{
    public static void main(String[] args) {
        Machine combo = new Camera();
        combo.show();
    }
}

From my understanding, I've created an Object called combo by instantiating the class of Camera, but am using the variable type of Machine, which is the superclass of Camera.

Now, since I'm creating an Object of Camera, I expect the method show() to print 13, but this code instead prints 7, as declared in the superclass Machine. I realize that the variable type of Machine confers the reference variable combo the method show(), but shouldn't the value return 13 since the Object itself is an instance of Camera? Thank you in advance for your help!

5
  • 1
    It prints 7 because the method show is not in the scope of the Camera class. Commented Dec 17, 2014 at 21:41
  • you are shadowing the info1 field. (a thing that Java should really not let you do in the first place) Commented Dec 17, 2014 at 21:50
  • @RyanJ: your comment is misleading. It is not a matter of the scope of show. Commented Dec 17, 2014 at 21:51
  • @njzk2 Maybe, but his question was why does 13 not print? You can answer that question in two ways: I chose to look at it from one perspective. Commented Dec 17, 2014 at 21:52
  • 1
    There is one simple rule: "fields are not polymorphic" (late binding is not involved for them). Commented Dec 17, 2014 at 21:54

3 Answers 3

3

There are two variables called info1 in this case - the variable in the subclass will not override the variable in the superclass, it will The show method prints the one that belongs to Machine.

The variable info1 declared in the subclass is said to hide the variable declared in the parent class, as explained in section 8.3 of the JLS:

If the class declares a field with a certain name, then the declaration of that field is said to hide any and all accessible declarations of fields with the same name in superclasses, and superinterfaces of the class.

Sign up to request clarification or add additional context in comments.

4 Comments

why did they do that?
@njzk2 same reason they let you use the same variable names in method parameters as instance fields. If you are explicit about how you use your variables, you shouldn't have any issues.
@njzk2 Why would you want to allow for variable overriding? :)
@manouti: not variable overriding, just no compile this kind of field hiding. It can only lead to errors.
2

The info1 variable in Camera isn't overloading the info1 variable in Machine, but rather is hiding it.

In this case the show() method can only see the info1 which is declared in its own class. Methods on Machine can't access fields which exist in sub-classes.

If you want to be able to change the value in a sub-class, you need to set it in a constructor like so:

class Camera extends Machine {
    public Camera() {
        super.info1 = 13;
    }
}

In this case, you are explicitly referencing the info1 in Machine and changing its value.

3 Comments

Though this doesn't detract from the concept of the answer, it would be worth noting that info1 needs protected or public access to be set in such a manner. Usage of a setter function would be required otherwise.
@RyanJ True, but if info1 were private then the hiding wouldn't cause as much confusion, since nobody would expect it to be overloadable in the first place. ;-)
Agreed, just thought I would mention it since the OP shows the declaration and how it's implicitly declared private. :)
1

As @manouti mentioned info1 are two different variables in each class (they are not overridden). However you could achieve the "required" functionality, without introducing a new variable by changing Camera class like this:

class Machine {
    int info1 = 7;

    public void show(){
        System.out.println(info1);
    }
}

class Camera extends Machine {

    public Camera() {
        info1 = 13;
    }

}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.