为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

呼啦一阵风 2022-06-23 20:31:47
当子类调用时,我试图让超类方法在子类方法/字段上运行。例如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”。为什么是这样?我该如何解决?或者有没有更好的方法来实现这个完全规避这个错误的对象结构?
查看完整描述

4 回答

?
慕容3067478

TA贡献1773条经验 获得超3个赞

链接字段不像虚拟方法调用那样使用动态调度。您的字段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

}


查看完整回答
反对 回复 2022-06-23
?
慕标5832272

TA贡献1966条经验 获得超4个赞

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



查看完整回答
反对 回复 2022-06-23
?
炎炎设计

TA贡献1808条经验 获得超4个赞

我很确定你也必须覆盖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());


查看完整回答
反对 回复 2022-06-23
?
慕雪6442864

TA贡献1812条经验 获得超5个赞

您通常不会像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有两个构造函数:


接受成本作为参数的受保护构造函数。

将成本设置为 3 的公共构造函数。

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


plain: 3

fancy: 6


查看完整回答
反对 回复 2022-06-23
  • 4 回答
  • 0 关注
  • 163 浏览

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号