java如何获取超类方法来修改子类字段



我有两个类A和B,如下

public class A {
    Number x;
    public A (){
        x = 10;
    }
    public void setX(Number x){
        //do a bunch of super complicated and lengthy stuff
        // afterwards set x
        this.x = x;
    }
}
public class B extends A{
    int x;
    public B(){
        super();
    }
    public void setX(int x){
        super.setX(x);
    }
    public int getX(){
        return x;
    }
}

我的主菜是

public class Main {
    public static void main(String[] args) {
        B test = new B();
        test.setX(9);
        System.out.println(test.getX());
    }
}

输出为0。我希望是9点。我意识到,在这个琐碎的例子中,我可以在B中的方法中写x=9,但如果这是一个更复杂的方法,我不想重写已经在超类方法中写的所有代码,那么我该如何实现呢?

编辑:在子类B中,我故意调用int变量x来隐藏超类变量x。假设超类中的setX方法在最终设置x之前做了大量其他事情。我希望它设置子类的x。这可能吗?这是一个微不足道的例子。在我的实际问题中,它要复杂得多。

编辑:实际问题是这个。我有一个名为ColorBinaryTree的类,它是BinaryTree的一个子类。唯一的区别是ColorBinaryTree类有一个颜色字段,所以我可以实现一个红黑树。BinaryTree类引用父对象、左对象和右对象,它们都是BinaryTree对象。ColorBinaryTree类具有相同的引用,但它们是ColorBinaryTree对象,而不是BinaryTrees对象。我有一堆处理树的方法。下面的就是一个例子

public BinaryTree<E> root() {
    if (parent == null) return this;
    else return parent.root();
}

在我的子类中,我需要重写它,这样我就可以进行协变返回类型并返回ColorBinaryTree对象。但如果我能在子类方法中调用超类方法,那就太好了。但似乎如果我调用超类方法,它会查看超类的parentfield。我希望它查看子类的父字段。

让我们从这两个变量命名为x这一事实开始——就编译器而言,这完全是巧合。这不像B.x"覆盖A.x。如果你想要多态行为,你必须使用方法。

现在您可以在B:中覆盖setX

@Override
public void setX(Number x)
{
    this.x = x.intValue();
}

您可能希望将其命名为super.setX()

如果你能举一个更现实的例子,那会有所帮助——我会避免这样的设计。。。

当您使用泛型时,您使用Java 5。用更具体的返回类型覆盖方法:

class BinaryTree<E> {
  public BinaryTree<E> root() {
    if (parent == null) return this;
    else return parent.root();
  }
}
class ColorBinaryTree<E> extends BinaryTree<E> {
  @Override
  public ColorBinaryTree<E> root() {
    return (ColorBinaryTree<E>)super.root();
  }
}

或者可以使用更复杂的通用解决方案:

abstract class AbstractBinaryTree<E, T extends AbstractBinaryTree<E,T>> {
  T parent;
  public T root() {
    if (parent == null) return (T)this;
    else return parent.root();
  }
}
class BinaryTree<E> extends AbstractBinaryTree<E, BinaryTree<E>>{
}
class ColorBinaryTree<E> extends AbstractBinaryTree<E, ColorBinaryTree<E> {
}

您已经在子类中重新定义了x。去掉intx声明并删除setX方法的"super."部分,使其只显示为:"this.x=x"。

问题的根源是,您正在更改类A中定义的x,然后在类B中提供初始化为0的值。

您从子类中输出私有int x,并在超类中设置Number变量。

从类B中删除"x"变量。方法getX()返回的是该变量,而不是基类中的变量。

如果没有自己的成员(只要A中的x不是私有的),这个解决方案怎么办:

public class B extends A {
  public void setX(int x){
    super.setX(x);
  }
  public int getX(){
    return x.intValue();
  }
}

在类层次结构中具有相同名称的成员从来都不是一个好的设计!

我刚才也遇到了同样的问题,当然还有你的问题。

您可以做的一件事是将ColorBinaryTree类的构造函数中的字段parentleftright重新初始化(不要构造具有相同名称的新字段)为ColorBinaryTree对象。

如果您的类确实是BinaryTree的子类,并且这些字段不是私有的或包私有的,那么这应该是可能的。

现在,这些字段将是ColorBinaryTree对象,但仍将被视为BinaryTree对象,因为这就是它们在超类(BinaryTree)中声明的内容。为了克服这个问题,只要有必要,就可以简单地将它们强制转换为ColorBinaryTree对象。

最新更新