在Java中从子类构造函数调用超类

13

我正在尝试创建一个构造函数,它以一个字段作为参数,然后将它放入存储在超类中的字段中。这是我正在使用的代码:

public crisps(String flavour, int quantity) {
    this.flavour = super.getFlavour();
    this.quantity = quantity;
}

在父类中,我已经初始化了该字段为

private String flavour;

我有一个访问器方法

public String getFlavour() {
    return flavour;
}

我遇到了一个错误 "flavour在超类中具有私有访问权限",但我认为这不应该有影响,因为我正在调用返回它的字段的访问器方法?


嗯,你所拥有的应该可以正常工作。你确定你向我们展示的是真实的代码吗? - Sotirios Delimanolis
1
请发布一个 SSCCE 来复现您的问题。 - Luiggi Mendoza
titlecrisps 中声明还是在父类中声明? - Sotirios Delimanolis
标题是来自另一个类的错误,应该说味道。 - user215732
4个回答

22

你应该做的:

为你的父类添加一个构造函数:

public Superclass {
    public SuperClass(String flavour) {
       // super class constructor
       this.flavour = flavour;
    }
}

在薯片的课程中:

public Crisps(String flavour, int quantity) {
    super(flavour); // send flavour to the super class constructor
    this.quantity = quantity;
}

 

评论

对于你的问题,我有一些评论:

"在超类中,我已经用“”初始化了该字段。

private String flavour;

这不是一个初始化,而是一个声明。初始化是指设置一个值。

“我得到了一个错误信息‘flavour在超类中具有私有访问权限’但我认为这并不重要,因为我正在调用返回其字段的访问器方法?”

当你调用访问器(也称为getter)时,如果getter的可见性是可以的的。你代码中的问题是:

this.flavour = 

因为风味不是在薯片类上声明的字段,而是在父类上声明的,所以您不能直接访问像那样。 您应该使用我的建议或在父类上声明一个setter:

public void setFlavour(String flavour) {
    this.flavour = flavour;
}

然后你可以在子类中使用它:

public Crisps(String flavour, int quantity) {
    this.quantity = quantity;
    super.setFlavour(flavour);
}

1
@ipinto.eu 虽然你的答案和解决方案是正确的,但你在答案中提供的最后一种替代解决方案(使用超类的 setter)违反了继承规则,我想,它会出现"Overridable method call in constructor"问题。因此,你最后的替代解决方案并不是一个实际的解决方案,而是会在代码中引入错误。我认为,super.setFlavour(flavour) 应该可以解决问题。 - Sajib Acharya
我理解并同意;我必须说,这个例子是为了讨论而存在的。我喜欢你使用super进行调用的建议,其他选项(和不同的哲学)是将你的setter方法设为final(无法被覆盖)。 - lpinto.eu

2
public crisps(String flavour, int quantity)
{
    super(flavour);
    this.quantity = quantity;
}

这应该像文档中描述的那样工作。


2

制作

    private String flavour;

如果你不将字符串定义为public,那么你的子类就无法访问它。你的超类不知道任何子类的存在。根据Java文档,“private”会使任何变量和方法仅在声明了私有变量或方法的类中可用,没有任何类可以访问它,即使是子类也不行。 一旦你修改了访问修饰符,就不会出现任何错误。


2

flavour是私有的。虽然你是从公共方法中读取它,但你正在将它赋值给一个私有字段,并且你可能没有在这个类中声明它。

你可以在父类中将flavour设置为protected或者定义一个setter方法。

不过最终你的代码并没有真正意义上的可执行性。即使编译通过,它也只是:flavour = flavour。也许你应该重新考虑一下你想要做什么。

我认为你可能需要更深入掌握Java和面向对象编程。

http://docs.oracle.com/javase/tutorial/java/concepts/

你应该从这里开始。


有没有办法通过调用公共方法getFlavour来实现呢? - user215732
@user215732 getFlavour 就是获取 flavour。你不能使用它来为 flavour 赋值。如果它返回一个可变对象,那么你可以修改实际的 flavour,但在这种情况下,字符串是不可变的。 - Cruncher
1
@user215732,你的 crisps 构造器有一个 flavour 参数,但是根据目前你的代码实现来看,你并没有使用它。 - ajb
@Cruncher 我认为 OP 想要设置值,而不是获取值。此外,OP,可以研究一下super构造函数。 - Sotirios Delimanolis
@SotiriosDelimanolis 我同意,那很可能是他的意思。我想补充一点,除非你需要从其他类设置这个变量,否则最好将setter设置为protected而不是public。super构造函数可能更好。 - Cruncher
显示剩余3条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接