【问题标题】:In Java how to refer subclass variable without declaring that variable in parent class?在Java中如何引用子类变量而不在父类中声明该变量?
【发布时间】:2018-03-16 02:19:22
【问题描述】:
public class MyTest {
    public static void main(final String[] args) {
        B b = new B();
        b.print();
    }
}

class A {
    private final int x = 5;

    protected int getX() {
        return x;
    }

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

class B extends A {
    private final int x = 10;

    @Override
    protected int getX() {
        return x;
    }


}

在这个例子中,我需要在父类中打印子类的值。 它工作正常。没有任何问题。 现在它正在打印 10。 但我不想在父 class A 中定义该属性。

因为在这个例子中这个x 数据类型非常简单。所以没有问题。 但在实时我想使用其他数据类型,可能是另一个类变量或List<something>,它们有大量数据。

所以最终我不希望将该值存储在Class A 中。 因为它是冗余数据。它会在我的休眠中减慢速度。 请让我知道,如何在不在父类中声明变量的情况下实现这一点。但是我仍然需要在父类中使用子类变量。

【问题讨论】:

  • 那就不要在那里声明了!从A 中删除x,一切应该仍然有效。
  • @Sweeper,它不起作用,因为父母的getX 使用它
  • @AndrewTobilko 然后从A 中删除getX。我看不出有它的意义。并将print 移动到BA 基本上不需要。
  • @Sweeper,为子类提供接口

标签: java class oop polymorphism parent-child


【解决方案1】:

抽象你的 A 类和 getX();方法。

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

abstract class A {

    protected abstract int getX();

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

class B extends A {
    private final int x = 10;

    @Override
    protected int getX() {
        return x;
    }
}

并覆盖 toString 方法来代替你的 print 方法

@Override
public String toString() {
    return String.valueOf(getX());
}

最终代码

public class Test {
    public static void main(final String[] args) {
        B b = new B();
        System.out.println(b);
    }
}

abstract class A {

    protected abstract int getX();

    @Override
    public String toString() {
        return String.valueOf(getX());
    }
}

class B extends A {
    private static final int X = 10;

    @Override
    protected int getX() {
        return X;
    }
}

你也可以将你的 x 变量定义为静态

但正如 Andrew Tobilko 所说,如果 A 不代表有状态实体,您也可以考虑使用接口。

这当然是您的最佳解决方案,混合使用接口和抽象类

public class Test {
    public static void main(final String[] args) {
        B b = new B();
        System.out.println(b);
    }
}

interface MyInterface {
    int getX();
}

abstract class A implements MyInterface{
    @Override
    public String toString() {
        return String.valueOf(getX());
    }
}

class B extends A {
    private static final int X = 10;

    @Override
    public int getX() {
        return X;
    }
}

【讨论】:

  • 不,它不能。不能在接口中覆盖 Object 方法。但是我们可以定义一个默认方法 print 并在 j8 中创建一个 trait
【解决方案2】:

您需要父类中的getX,但您没有足够的信息来在那里实现此方法。

您可以将这个类声明为abstract,并用abstract 标记方法。这样做,您将方法实现的责任交给其子类并防止父字段声明。

如果A 没有描述任何状态(仅操作/方法),您应该考虑将其替换为接口。目前的状态是这样的。

【讨论】:

    【解决方案3】:

    您可以使父类抽象,消除父类中的属性,使 getX() 抽象,然后将 print() 保留为具体。然后在子类中使用 getX() 的具体实现即可。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2022-11-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-09-05
      • 2023-03-28
      相关资源
      最近更新 更多