-4
class Feline {
    public String type = "f ";

    public Feline() {
        System.out.print("feline ");
    }
}

public class Cougar extends Feline {

    public Cougar() {
        System.out.print("cougar ");
    }
    void go() {
        type = "c ";
        System.out.print(this.type + super.type);
    }
    public static void main(String[] args) {
        new Cougar().go();
    }
}

In this code output is coming as feline cougar c c and when I am changing subclass variable as String Type = "c" means assigning new String type then answer is coming as feline cougar f f please let me know how this and super keyword is working in this subclass method?

nbrooks
  • 18,126
  • 5
  • 54
  • 66
Sanat
  • 267
  • 1
  • 5
  • 16
  • Your question is absolutely unclear. Please read [mcve] and beyond that do some research/study to at least be able to express your problem in a way we could help with. – GhostCat Aug 20 '17 at 07:17
  • Your variable type isn't declared - the insufficient code in your question would not even compile... – GhostCat Aug 20 '17 at 07:18
  • If you declare a `type` variable in `Cougar` it shadows the one in `Feline`, so `this.type` and `super.type` refer to different variables. If you don't, they refer to the same variable. – user207421 Aug 20 '17 at 07:20
  • which variable are you talking about? type variable is already publically defined and in the subclass, we are just changing the value of the same variable – Sanat Aug 20 '17 at 07:22
  • 2
    @Sanat There is no `type` variable in the subclass in the code you posted. Please read what I wrote again. When you *added* `String type = "c"` into the subclass you introduced the shadowing I spoke of. – user207421 Aug 20 '17 at 07:33
  • that's absolutely fine "type" given in the subclass is shadowing the actual value and this is the actual question which is being asked in OCPJP java. and the output of this code is coming as "feline cougar c c" – Sanat Aug 20 '17 at 07:46
  • That's what I said. Your point? – user207421 Aug 20 '17 at 07:53
  • I think my point is already cleared by "Sweeper". – Sanat Aug 20 '17 at 08:05

2 Answers2

1

Now I see that . Your Cougar class is missing "type" variable. I have checked in my code and this.type and super.type are the same variable. Setting type = "c" is equal to this.type = "c" and super.type="c" because they point same field.

Edited: Write something like this

class Cougar extends Feline {
    public String type = "c ";
    ....
} 
John Tribe
  • 1,407
  • 14
  • 26
  • that's fine, you have created a new variable at subclass level and it is working as expected, but my question was to understand the behavior of the code posted by me and why I am able to shadowing the type variable at method level and not at subclass level. ? – Sanat Aug 20 '17 at 08:18
  • In your case you have "only one field". Then why are you thinking that this.type and super.type should give you different field, when you have only "ONE". As I say in answer super.type and this.type point same field. This is default behavior, if you have "ONE" field . You did'n shadow variable you just set new value to only field you have. I hope that helps. – John Tribe Aug 20 '17 at 08:22
1

type is an unqualified name, and refers to a local variable, parameter, or field.
this.type refers to a field accessible to the current class.
super.type refers to a field accessible to the base class.

Since the subclass Cougar does not have a field named type, both this.type and super.type refers to the type field declared in base class Feline. In your example, there is no difference between this and super.

The statement type = "c "; in method go() is unqualified, and since there is no local variable or parameter by that name, it also refers to field type of base class Feline. As such, type, this.type, and super.type all refer to the one and only field named type.

If the statement in method go() is changed to String Type = "c";, then it defines a differently named local variable. Remember, Java names are case-sensitive, so Type and type are not the same name. So, field type retains the initialized value of "f ".

If you intended to change the statement in method go() to String type = "c";, then it defines and initialize a local variable named type. By nature, it cannot update field type, since the initializer applies to the newly declared local variable. So, field type retains the initialized value of "f ".

If you first declare the local variable in method go() using String type;, then assign it like you original code does using type = "c";, then the unqualified name refers to the local variable, not the field, by that name. The local variable is hiding the field of the same name. So, once again, field type retains the initialized value of "f ".

Andreas
  • 154,647
  • 11
  • 152
  • 247
  • why I am able to shadowing the type variable at method level and not at subclass level. ? – Sanat Aug 20 '17 at 08:45
  • @Sanat I don't understand your comment. You can hide base class field using a subclass field *and* using a local variable, both at the same time, if you want. If you do both, then subclass field hides super class field, and local variable hides both fields, in which case `type`, `this.type` and `super.type` would refer to 3 different variables. – Andreas Aug 20 '17 at 08:50
  • Agree.. but When I am writing type = "c" at subclass level (not in method), it is giving me compile time error as "Syntax error on token "type", VariableDeclaratorId expected after this token" means I have to assign String type, but at method level I was just changing the variable value which was declared in parent class – Sanat Aug 20 '17 at 08:56
  • @Sanat `type = "c"` is an assignment statement. Statements must be in a method, constructor, or initializer block. That's why it cannot be outside a method. You can put it in an initializer block, which is basically the same as putting it inside the constructor, if that is what you want. – Andreas Aug 20 '17 at 16:08
  • Thanks, man ! you cleared my doubt, I understood now. – Sanat Aug 21 '17 at 12:58