17

我有以下情况:

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

}

执行代码时,输​​出为:5。

如何通过父类方法访问子类(B)变量(x)?

这是否可以在覆盖 print() 方法的情况下完成(即在 B 中取消注释)?

[这很重要,因为在重写时我们将不得不再次重写 print() 方法的整个代码]

已编辑

更多说明:-

  • 问题的动机是使用来自其父类方法的子类私有变量的值。这不需要更改父类私有变量的值即可达到预期的结果。
  • 不过,这里发布的答案让我得到了我想要的答案,我在下面发布了这个答案。

(感谢大家的时间和帮助)

4

5 回答 5

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

已编辑

以下是使用抽象类和方法解决类似场景的一般答案:

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();
    }
}
于 2012-07-04T02:02:20.803 回答
8

在阅读了此处发布的所有答案后,我得到了我想要的东西。以下是我认为是我问题的最佳答案:

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

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

于 2012-07-28T12:30:05.490 回答
3

要解决您的问题,您必须在父类 A 中定义字段,如受保护(因此它将在子类上继承)并在子类 B 的构造函数中设置字段值 x。打印方法也继承自一个类,因此您可以直接从父类调用它。

我希望这可以帮助你。

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
    }

}
于 2014-08-01T15:26:39.733 回答
0

您应该为您想要的值公开一个 getter,并在子类中覆盖它。

像这样:

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

}
于 2012-07-04T01:40:12.043 回答
0

您始终可以将其添加到构造函数中:

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

}

它在您尝试时不起作用的原因是默认值只被评估一次。因此,当它在 A 中默认为 5 时,即使您在 B 中使用默认 10,它也会保持为 5。

于 2012-07-04T01:40:30.933 回答