我试图让超类方法在被子类调用时在子类方法/字段上运行。例如
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”。为什么是这样?我该如何解决?还是有一种更好的方法来实现可以完全避免该错误的对象结构?
答案 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
有两个构造函数:
子类FancyCoffeeMachine
调用受保护的超类构造函数,其成本为6。因此,cost
变量设置为6,并且getCost()
将在运行它时返回该值:>
plain: 3
fancy: 6