Java get超类方法在被子类调用时使用子类实例方法

时间:2019-02-17 19:28:57

标签: java oop inheritance

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

11.2.0.4

我要打印6,但是要打印3。我想使它尽可能地干,所以我试图避免做第二个getCost()方法。有什么办法吗?当由子类调用时,如何获得超类方法以使用子类变量?方法也会发生同样的事情:如果我有

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

即使我在FancyCoffeeMachine上调用makeCoffee,输出也将是“ Coffee cost 3”。为什么是这样?我该如何解决?还是有一种更好的方法来实现可以完全避免该错误的对象结构?

4 个答案:

答案 0 :(得分:2)

链接字段不像虚拟方法调用那样使用动态分配。您的字段FancyCoffeeMachine.cost只是隐藏字段CoffeeMachine.cost

要实现所需的功能(即FancyCoffeeMachine成本较高),您只需在CoffeeMachine.cost中的初始化程序块或构造函数中的FancyCoffeeMachine字段中设置新值即可。

public class CoffeeMachine {
    protected int cost = 3;

    protected int getCost() {
        return cost;
    }
}
public class FancyCoffeeMachine extends CoffeeMachine{
    {cost = 6;} // <- sets CoffeeMachine.cost
}

答案 1 :(得分:0)

我很确定您也必须在getCost()上覆盖FancyCoffeeMachine

public class FancyCoffeeMachine() extends CoffeeMachine{
    protected int cost = 6;

    protected int getCost() {
        return cost;
    }
}

但是,如果我想实现这一目标,我将要做的是将CoffeeMachine做成这样的抽象

abstract class CoffeeMachine {
    private int cost;

    CoffeeMachine(int cost) {
        this.cost = cost;
    }

    int getCost() {
        return cost;
    }
}

然后像这样在我的超类上扩展它

class FancyCoffeeMachine extends CoffeeMachine {
    FancyCoffeeMachine(int cost) {
        super(cost);
    }
}

并这样称呼

FancyCoffeeMachine fancyCoffeeMachine =  new FancyCoffeeMachine(6);
System.out.println(fancyCoffeeMachine.getCost());

答案 2 :(得分:0)

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

答案 3 :(得分:0)

通常不会在子类中重新定义cost之类的受保护字段。相反,您将为子类提供一种在构造对象时设置成本的方法。看这个:

public class Scratch {
    public static class CoffeeMachine {
        protected int cost;

        public CoffeeMachine() {
            this(3);
        }

        protected CoffeeMachine(int aCost) {
            cost = aCost;
        }

        public int getCost() {
            return cost;
        }
    }

    public static class FancyCoffeeMachine extends CoffeeMachine{
        public FancyCoffeeMachine() {
            super(6);
        }
    }

    public static void main(String[] args) {
        System.out.printf("plain: %d\n", new CoffeeMachine().getCost());
        System.out.printf("fancy: %d\n", new FancyCoffeeMachine().getCost());
    }
}

(不必担心两个CoffeeMachine类都被声明为静态的事实。就是这样,它们都可以在一个文件中定义。)

基类CoffeeMachine有两个构造函数:

  1. 接受费用作为参数的受保护的构造函数。
  2. 将成本设置为3的公共构造函数。

子类FancyCoffeeMachine调用受保护的超类构造函数,其成本为6。因此,cost变量设置为6,并且getCost()将在运行它时返回该值:

plain: 3
fancy: 6