2

I want to write a program in java that consists of three classes, A, B, and C, such that B extends A and C extends B. Each class defines an instance variable (named "x").

how can I write a method in C to access and set A's version of x to a given value, without changing B or C's version?

I tried super.x but It wasn't true.

any help? thanks for your attention in advance

bofredo
  • 2,348
  • 6
  • 32
  • 51
Linda
  • 251
  • 1
  • 6
  • 16
  • 1
    [This](http://stackoverflow.com/questions/586363/why-is-super-super-method-not-allowed-in-java) might be some good reading regarding the idea of super.super.x, which is what you're trying to do. – nhgrif Sep 27 '13 at 18:22
  • you need some modifier public methods – nachokk Sep 27 '13 at 18:25

3 Answers3

3

You can access A's version of x like this:

((A)this).x

as long as x wasn't declared private in class A. I've just tested it.

Note that for fields, there is no overriding (as there is for methods). Thus, for an object of class C, there will be three x fields, but two of them can't be accessed normally because they are hidden by the other field named x. But casting the object as above will allow you to get at it, if it would have been visible if not hidden.

I think it is very poor practice to declare fields of the same name in a class and its subclasses. It's confusing. It can happen legitimately if, say, you have a class A and you later change the implementation of A and add a new private field z; in that case, it may not be possible to make sure no subclasses of A already have a field z, since you don't even always know what all the subclasses are (if A is a class you've distributed publicly, for instance). I think it's for that reason that Java allows you to have fields of the same name, and why the hiding rules are the way they are, because it allows things like this to work without breaking all the other subclasses. Other than that, though, I recommend not having fields of the same name in superclasses and subclasses. Perhaps if they're all private it might be OK, though.

ajb
  • 31,309
  • 3
  • 58
  • 84
2

I misread your question. You can't do what you're trying to do.

Extending classes means adding information in several layers, ultimately resulting in one object. Although there are multiple layers, this doesn't mean that the layers are separate of eachother.

The variable X will be defined at one level (probably A) and after that the other classes will use this variable (if it's declared protected), but they won't have their own copy of it. You can only access your direct superclass.
This class might give you additional access to its own superclass, but you don't have direct contact with the super-super class.

Jeroen Vannevel
  • 43,651
  • 22
  • 107
  • 170
  • This doesn't completely address the question. – nhgrif Sep 27 '13 at 18:19
  • 2
    I get the impression that he still means something different from what you understand. `Class A` has a `public int x`. `Class B` also has a `public int x`, but can access the `x` in `Class A` via `super.x`. `Class C` ALSO has a `public int x`, but can access the `x` in `Class B` via `super.x`. What the poster wants to do is access `Class A`'s `x` via `Class C` (so like `super.super.x`). He can't do this though. – nhgrif Sep 27 '13 at 18:27
2

Do the following

public static void main(String[] args) throws Exception {
    C c = new C();
    System.out.println("c:" + c.x);
    System.out.println("a:" + ((A)c).x);
    c.changeAX();
    System.out.println("c:" + c.x);
    System.out.println("a:" + ((A)c).x);
}

static class A {
    int x;
}

static class B extends A {
    int x;
}

static class C extends B {
    int x;

    public void changeAX() {
        ((A)this).x = 4;
    }
}

Fields are resolved relative to the declared type of the reference. The above prints

c:0
a:0
c:0
a:4

The field will have to have at least protected visibility.


You don't want to be hiding class members, it's bad practice because it can easily confuse anyone trying to figure out which member you are referring to.

Sotirios Delimanolis
  • 274,122
  • 60
  • 696
  • 724