子类调用时Java获取超类方法以使用子类实例方法

当子类调用时,我试图让超类方法在子类方法/字段上运行。例如


public class CoffeeMachine() {

    protected int cost = 3;


    protected int getCost() {

        return cost;

    }

}


public class FancyCoffeeMachine() extends CoffeeMachine{

    protected int cost = 6;

}


main{

    FancyCoffeeMachine expensive = new FancyCoffeeMachine();

    System.out.println(expensive.getCost());

}

我希望它打印 6,但它会打印 3。我想让它尽可能 DRY,所以我试图避免创建第二个 getCost() 方法。有没有办法做到这一点?当子类调用时,如何获得使用子类变量的超类方法?方法也会发生同样的事情:如果我有


public class makeCoffee() {

    System.out.println("Coffee cost " + this.getCost());

}

即使我在 FancyCoffeeMachine 上调用 makeCoffee,输出也会是“Coffee cost 3”。为什么是这样?我该如何解决?或者有没有更好的方法来实现这个完全规避这个错误的对象结构?


呼啦一阵风
浏览 164回答 4
4回答

慕容3067478

链接字段不像虚拟方法调用那样使用动态调度。您的字段FancyCoffeeMachine.cost只是隐藏了该字段CoffeeMachine.cost。要实现您想要的(即具有更高成本的 FancyCoffeeMachine),您可以简单地CoffeeMachine.cost为初始化块或构造函数中的字段设置一个新值FancyCoffeeMachine。public class CoffeeMachine {&nbsp; &nbsp; protected int cost = 3;&nbsp; &nbsp; protected int getCost() {&nbsp; &nbsp; &nbsp; &nbsp; return cost;&nbsp; &nbsp; }}public class FancyCoffeeMachine extends CoffeeMachine{&nbsp; &nbsp; {cost = 6;} // <- sets CoffeeMachine.cost}

慕标5832272

您正在getCost从超类(CoffeeMachine)调用方法,因为您的子类(FancyCoffeeMachine)中没有它。而且您的超类对 subclass 及其字段一无所知cost。您还应该覆盖方法getCost以使其像您描述的那样工作。

炎炎设计

我很确定你也必须覆盖getCost()。FancyCoffeeMachinepublic class FancyCoffeeMachine() extends CoffeeMachine{&nbsp; &nbsp; protected int cost = 6;&nbsp; &nbsp; protected int getCost() {&nbsp; &nbsp; &nbsp; &nbsp; return cost;&nbsp; &nbsp; }}但是如果我想实现这个我会做的就是让 CoffeeMachine 像这样抽象abstract class CoffeeMachine {&nbsp; &nbsp; private int cost;&nbsp; &nbsp; CoffeeMachine(int cost) {&nbsp; &nbsp; &nbsp; &nbsp; this.cost = cost;&nbsp; &nbsp; }&nbsp; &nbsp; int getCost() {&nbsp; &nbsp; &nbsp; &nbsp; return cost;&nbsp; &nbsp; }}然后像这样在我的超类上扩展它class FancyCoffeeMachine extends CoffeeMachine {&nbsp; &nbsp; FancyCoffeeMachine(int cost) {&nbsp; &nbsp; &nbsp; &nbsp; super(cost);&nbsp; &nbsp; }}并这样称呼它FancyCoffeeMachine fancyCoffeeMachine =&nbsp; new FancyCoffeeMachine(6);System.out.println(fancyCoffeeMachine.getCost());

慕雪6442864

您通常不会像cost在子类中那样重新定义受保护的字段。相反,您将在构造对象时为子类提供一种设置成本的方法。看这个:public class Scratch {&nbsp; &nbsp; public static class CoffeeMachine {&nbsp; &nbsp; &nbsp; &nbsp; protected int cost;&nbsp; &nbsp; &nbsp; &nbsp; public CoffeeMachine() {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; this(3);&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; protected CoffeeMachine(int aCost) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; cost = aCost;&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; public int getCost() {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return cost;&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; }&nbsp; &nbsp; public static class FancyCoffeeMachine extends CoffeeMachine{&nbsp; &nbsp; &nbsp; &nbsp; public FancyCoffeeMachine() {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; super(6);&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; }&nbsp; &nbsp; public static void main(String[] args) {&nbsp; &nbsp; &nbsp; &nbsp; System.out.printf("plain: %d\n", new CoffeeMachine().getCost());&nbsp; &nbsp; &nbsp; &nbsp; System.out.printf("fancy: %d\n", new FancyCoffeeMachine().getCost());&nbsp; &nbsp; }}(不用担心这两个CoffeeMachine类被声明为静态的。这只是为了让它们都可以在一个文件中定义。)基类CoffeeMachine有两个构造函数:接受成本作为参数的受保护构造函数。将成本设置为 3 的公共构造函数。子FancyCoffeeMachine类以 6 的成本调用受保护的超类构造函数。因此该cost变量设置为 6,并getCost()在您运行它时返回该值:plain: 3fancy: 6
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Java