19

I have the following scenario :

public class A {

    private int x = 5;

    public void print()
    {
        System.out.println(x);
    }
}


public class B extends A {

    private int x = 10;

    /*public void print()
    {
        System.out.println(x);      
    }*/

    public static void main(String[] args) {
        B b = new B();
        b.print();
    }

}

On executing the code, the output is : 5.

How to access the child class(B's) variable(x) via the parent class method?

Could this be done without overriding the print() method (i.e. uncommenting it in B)?

[This is important because on overriding we will have to rewrite the whole code for the print() method again]

EDITED

More Clarification :-

  • The motive of the question is to use the value of a child class private variable from its parent class method. This doesn't require changing the value of the parent class private variable in order to achieve the desired result.
  • The answers posted here, though, led me to my desired answer, which I have posted below.

(Thanks all for your time and help )

7
  • When you want to print B's variable x, do you intend for x to be different from A's x, or should they be the same? Commented Jul 4, 2012 at 1:40
  • @WeiHao from the code it's obvious that the x in A is to be 5, the one in B is to be 10. He wants B.print() to output 10, because he's not happy with an output of 5. Thus he expects them to be different. Commented Jul 4, 2012 at 1:45
  • @Jayant It's not about the parent not having information, it doesn't. the problem is that the value of x isn't overridden during creation of B. Commented Jul 4, 2012 at 1:46
  • My main concern is that, here, the code in the parent class cannot be reused by the child. Could this code be reused? Commented Jul 4, 2012 at 1:46
  • @Jayant the code in the parent class can be reused, just look at my answer :). Your problem is that the value of x isn't updated when B is created, because default values are only evaluated once. Commented Jul 4, 2012 at 1:48

5 Answers 5

17
class A {
    private int x = 5;

    protected int getX() {
        return x;
    }

    protected void setX(int x) {
        this.x = x;
    }

    public void print() {
        // getX() is used such that 
        // subclass overriding getX() can be reflected in print();
        System.out.println(getX());
    }
}

class B extends A {
    public B() {
        // setX(10);  // perhaps set the X to 10 in constructor or in main
    }

    public static void main(String[] args) {
        B b = new B();
        b.setX(10);
        b.print();
    }
}

EDITED

Below is a general answer using abstract class and method to solve similar scenario:

abstract class SuperA {
    protected abstract Object getObj();

    public void print() {
        System.out.println(getObj());
    }
}

class A extends SuperA {
    @Override
    protected Object getObj() {
        // Your implementation
        return null; // return what you want
    }
}

class B extends A {
    @Override
    protected Object getObj() {
        // Your implementation
        return null; // return what you want
    }

    public static void main(String[] args) {
        B b = new B();
        b.print();
    }
}
Sign up to request clarification or add additional context in comments.

9 Comments

Nice all-around solution. This is pretty OOP =D. Also, very much C#-like.
@Shingetsu, Thanks, but I know nothing about C#, I plan to learn it but my job doesn't allow...
basically, C# is just an elegant version of Java. If you know Java well already you won't have much trouble learning it, though knowing .NET and C++ would come in handy =D.
This would work well. But it actually beats the motive of the question. What is required is to use the value of the variable from the child class in a parent class function.
Then you can just override getX() method and return the required value.
|
9

After reading all the answers posted here, I got what I was looking for. The following is what I feel is the best answer for my question :

public class A {
    private int x = 5;    
    protected int getX(){
        return x; 
    }    
    public void print(){
        System.out.println(getX());
    }
}
public class B extends A {
    private int x = 10;
    protected int getX(){
        return x; 
    }  
    public static void main(String[] args) {
        B b = new B();
        b.print();
    }
}

Setting up a protected getter and overriding it is better than overriding the print() method itself, as there could be any other huge method in place of the print method which might need to access the value of the child class variable(s).

2 Comments

@kakacii Yes, though VictorWong's answer does not answer the question precisely, people find it more useful. I have changed my choice. Thanks :)
@Jayant I can't see any difference between my general solution (not the first one, but edited one) and your answer here, except you replace obj with x. No offense, but I want to know why my solution is not precise enough.
3

To solve your question you have to define the fields in the parent class A like protected (so it will be inherited on the child class) and set the field value x inside the constructor in the child class B. The print method is also inherited from A class so you can invoke it directly from parent class.

I hope this can help you.

public class A 
{
    // fields declaration 
    protected int x = 5;

    public void print()
    {
        System.out.println(x);
    }
}



public class B extends A 
{

    public B()
    {
        // set child x value. The field have been defined in the parent class
        x = 10;
    }

    public static void main(String[] args) 
    {
        A a = new A();
        a.print(); // print 5

        B b = new B();
        b.print(); // print 10
    }

}

Comments

0

You can always add it to the constructor:

public class B extends A {

    //this line is unnecessary: private int x = 10;

    /*public void print()
    {
        System.out.println(x);      
    }*/

    public B()
    {
        x=10;
    }


    public static void main(String[] args) {
        B b = new B();
        b.print();
    }

}

The reason it won't work as you try it is that default values only get evaluated once. So when it's default 5 in A, it stays 5 even though you used default 10 in B.

5 Comments

Firstly, changing x in the B's constructor won't work if the visibility of x is private. Secondly, even if we make the visibility of x to be protected, it would change the value of the variable x in the parent class. What is required is not to change the value of the variable in the parent class but to use the value of the child class variable.
@Jayant the child class variable DOESN'T EXIST. You make a variable in the parent, give it a default value. Default values are evaluated once. You give THE SAME VARIABLE another default value in B, but the default value has already been evaluated in A. When you make B, IL 1st evaluates default value for x in A, then x in B, but since x already got evaluated in A, the line private int x = 10; does absolutely nothing.
I do not understand what you are trying to say. Clearly the statement private int x = 10 in class B allocates some new memory for the variable x in class B and it is completely independent to the variable x in A.
@Jayant it is NOT completely independent from the variable in A. Quite the opposite, the variable in A is private, and as such is inherited. The statement private in x = 10; does not make a new variable x. Imagine writing: public class A { private int x = 5; private int x = 10; }. Makes no sense? That's the same situation. private fields are inherited (but cannot be accessed). so the statment private int x = 10; actually does nothing at all.
@Jayant you want to either make an entirely new variable in the child class, or only use the one in the parent class. There is no "in between". In the 1st case, you have to change the name. In the latter case, you have to make it protected.
0

You should expose a getter for the value you want and override that in the child class.

Like so:

public class A {

    private int x = 5;

    public void print()
    {
        System.out.println(getX());
    }

    protected void setX(int x)
    {
        this.x = x;
    }

    protected int getX()
    {
        return x;
    }

}


public class B extends A {

    /*public void print()
    {
        System.out.println(x);      
    }*/

    public B()
    {
        setX(10);
    }

    public static void main(String[] args) {
        B b = new B();
        b.print();
    }

}

6 Comments

That works too, though what if x has to be changed at one point? This is restricted to the example given.
Make a setter of X also then.
@VictorWong This isn't a real getter, the variable isn't actually there.
This is a great answer (solves the problem). It would be nice to declare private variable and return it in the getX() method instead of just returning the values directly. If you allow, i could edit your answer to do the above (and accept it).
i update the answer to provide a setter which the sublass uses on its constructor. This should have the same effect.
|

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.