有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

继承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。在最终设置x之前,假设超类中的setX方法做了大量其他事情。我希望它设置子类的x。这可能吗?这是一个微不足道的例子。我的实际问题要复杂得多

编辑:实际问题是这个。我有一个名为ColorBinaryTree的类,它是BinaryTree的一个子类。唯一的区别是ColorBinaryTree类有一个颜色字段,因此我可以实现一个红黑树。BinaryTree类引用了parent、left和right,它们都是BinaryTree对象。ColorBinaryTree类具有相同的引用,但它们是ColorBinaryTree对象,而不是BinaryTree对象。我有很多方法可以操纵这棵树。下面就是一个例子

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

在我的子类中,我需要重写它,以便执行协变返回类型并返回ColorBinaryTree对象。但如果我能在我的子类方法中调用超类方法,那就太好了。但是,如果我调用超类方法,它会查看超类的父字段。我想让它看看子类的父字段


共 (6) 个答案

  1. # 1 楼答案

    当您使用泛型时,您使用的是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> {
    }
    
  2. # 2 楼答案

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

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

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

    你可能想让它叫super.setX()

    不过,如果你能给出一个更现实的例子,这会有所帮助——我会先避免这样的设计

  3. # 3 楼答案

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

  4. # 4 楼答案

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

  5. # 5 楼答案

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

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

    在类层次结构中拥有相等的命名成员从来都不是一个好的设计

  6. # 6 楼答案

    你在你的孩子班上定义了x。取出int x声明并删除“super”是setX方法的一部分,所以它的内容是:“this.x=x”

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