简体   繁体   English

Java:使用父类方法访问子类变量

[英]Java : Using parent class method to access child class variable

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. 在执行代码时,输​​出为:5。

How to access the child class(B's) variable(x) via the parent class method? 如何通过父类方法访问子类(B)变量(x)?

Could this be done without overriding the print() method (ie uncommenting it in B)? 这可以在覆盖print()方法的情况下完成(即在B中取消注释)吗?

[This is important because on overriding we will have to rewrite the whole code for the print() method again] [这很重要,因为在重写时我们必须再次重写print()方法的整个代码]

EDITED 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 ) (感谢您的所有时间和帮助)

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 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();
    }
}

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). 设置受保护的getter并覆盖它比覆盖print()方法本身更好,因为可能有任何其他巨大的方法代替print方法,可能需要访问子类变量的值。

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. 要解决您的问题,您必须在父类A中定义像受保护的字段(因此它将在子类上继承)并在子类B中的构造函数内设置字段值x。print方法也继承自一个类,所以你可以直接从父类调用它。

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
    }

}

You should expose a getter for the value you want and override that in the child class. 您应该为您想要的值公开一个getter,并在子类中重写它。

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();
    }

}

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. 因此,当它在A中的默认值为5时,即使您在B中使用默认值10,它也会保持为5。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM