java 覆盖子类中的 Setter

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/15631762/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-31 20:19:33  来源:igfitidea点击:

Override Setter in Subclass

javasettergetter-setteroverriding

提问by Energyfellow

I'm stuck with a problem here. I want to change the setter from a attribute from the superclass (parent class) in my subclass (child) however when I overide this method in my subclass I can't access my private attributes from the supperclass. And the point is, they have to stay private.

我在这里遇到了一个问题。我想从我的子类(子类)中的超类(父类)的属性更改设置器,但是当我在子类中覆盖此方法时,我无法从超类访问我的私有属性。关键是,他们必须保持私密。

Superclass (problem: setMinimumVoorraad(int voorraad);)

超类(问题:setMinimumVoorraad(int voorraad);)

package domein;

包域;

public abstract class Artikel implements Weegbaar
{
    private String omschrijving;
    private double prijs;
    private int aantalInStock;
    private int minimumVoorraad;

    public Artikel(String omschrijving, double prijs, int aantalInStock, int minimumVoorraad)
    {
        this.setOmschrijving(omschrijving);
        this.setPrijs(prijs);
        this.setAantalInStock(aantalInStock);
        this.setMinimumVoorraad(minimumVoorraad);
    }

    @Override
    public String toString()
    {
        String output = String.format(" \n omschrijving: %s \n prijs:  %f \n In stock %d (minimumvoorraad = %d) \n", this.omschrijving, this.prijs, this.aantalInStock, this.minimumVoorraad);
        return output;
    }
//----Getters----
    public String getOmschrijving() {
        return omschrijving;
    }

    public double getPrijs() {
        return prijs;
    }

    public int getAantalInStock() {
        return aantalInStock;
    }

    public int getMinimumVoorraad() {
        return minimumVoorraad;
    }

//----Setters----
    public void setOmschrijving(String omschrijving) {
        this.omschrijving = omschrijving;
    }

    public void setPrijs(double prijs) {
        this.prijs = prijs;
    }

    public void setAantalInStock(int aantalInStock) {
        this.aantalInStock = aantalInStock;
    }

    public void setMinimumVoorraad(int minimumVoorraad) 
    {
        if(minimumVoorraad < 2)
            this.minimumVoorraad = 3;
        else
            this.minimumVoorraad = minimumVoorraad;
    }


}

Subclass

子类

package domein;


public class Food extends Artikel
{

    private String houdbaarheidsDatum;
    private double nettoGewicht;

    public Food(String omschrijving, double prijs, int aantalInStock, int minimumVoorraad, String houdbaarheidsDatum, double nettoGewicht)
    {
        super(omschrijving, prijs, aantalInStock, minimumVoorraad);
        this.setHoudbaarheidsDatum(houdbaarheidsDatum);
        this.setNettoGewicht(nettoGewicht);
    }

    @Override
    public boolean isWeegbaar()
    {
        return true;
    }


//----Getters----
    public String getHoudbaarheidsDatum() {
        return houdbaarheidsDatum;
    }

    public double getNettoGewicht() {
        return nettoGewicht;
    }

//----Setters----
    public void setHoudbaarheidsDatum(String houdbaarheidsDatum) {
        this.houdbaarheidsDatum = houdbaarheidsDatum;
    }

    public void setNettoGewicht(double nettoGewicht) {
        this.nettoGewicht = nettoGewicht;
    }

    @Override
    public void setMinimumVoorraad(int minimumVoorraad) 
    {
        if(minimumVoorraad < 5)
            this.minimumVoorraad = 6;
        else
            this.minimumVoorraad = minimumVoorraad;
    }


}

Someone who can help me? Thanks in advance.

谁能帮助我?提前致谢。

采纳答案by SeKa

The answer given above by NPE is absolutely the best way to go about solving this problem. It is elegant and honors basic inheritance contracts between superclass and subclass. Even in your original post, the subclass is actually more restrictive than the superclass, so doing something like:

NPE 上面给出的答案绝对是解决这个问题的最佳方法。它优雅并尊重超类和子类之间的基本继承契约。即使在您的原始帖子中,子类实际上也比超类更具限制性,因此请执行以下操作:

@Override
public void setMinimumVoorraad(int minimumVoorraad) 
{
    if(minimumVoorraad <= 5)
        super.setMinimumVoorraad(6);
    else
        super.setMinimumVoorraad(minimumVoorraad);
}

exactly as NPE suggested would probably work. (Note how I modified your iftest. Not sure if it's a typo, but in the original implementation 5would be a valid minimum, but input like 4would set it to 6.)

完全按照 NPE 的建议可能会起作用。(注意我是如何修改你的if测试的。不确定它是否是一个错字,但在原始实现5中将是一个有效的最小值,但输入 like4会将其设置为6。)

Other (possibly acceptable) patterns would be to:

其他(可能可接受的)模式是:

  1. Make the members in your Parent class protected, which would give visibility. (Realize that you did mention a privaterestriction; this pattern is solely mentioned to provide a more complete overall answer.)
  2. Delegate the validation logic to another method (that is non-private). This way the child can override the validation method.
  1. 在您的 Parent 类中创建成员protected,这将提供可见性。(意识到您确实提到了private限制;仅提及此模式是为了提供更完整的整体答案。)
  2. 将验证逻辑委托给另一个方法(即非私有的)。通过这种方式,孩子可以覆盖验证方法。

And now on to the (probably unacceptable) pattern of using Java reflection:

现在谈谈使用 Java 反射的(可能是不可接受的)模式:

@Override
public void setMinimumVoorraad(int minimumVoorraad) {

    try {
        Field field = this.getClass().getSuperclass().getDeclaredField("minimumVoorraad");
        field.setAccessible(true);

        if(minimumVoorraad <= 5)
            field.set(this, 6);
        else
            field.set(this, minimumVoorraad);

        field.setAccessible(false);
    }
    catch(NoSuchFieldException | IllegalAccessException e) {
        // do something
    }
}

It's worth noting that if you never ever do this in your entire life you will probably be the better for it. Not only does it completelybreak all contracts, but it relies on hard-coded Strings to do field name lookups, which in and of itself is pretty painful. But it does exist. And no good answer (already given above by NPE) would be complete without an example of how notto do something...

值得注意的是,如果您一生中从未这样做过,那么您可能会变得更好。它不仅完全打破了所有约定,而且还依赖于硬编码的字符串来进行字段名称查找,这本身​​就非常痛苦。但它确实存在。如果没有一个关于如何做某事的例子,那么好的答案(上面已经由 NPE 给出)是不完整的......

回答by NPE

One possibility is to implement the subclass's setter in terms of the superclass's setter (which, presumably, you do have access to).

一种可能性是根据超类的 setter 实现子类的 setter(大概您确实可以访问)。

For example, assuming the setter is setFoo, then the subclass's version might be:

例如,假设 setter 是setFoo,那么子类的版本可能是:

public void setFoo(Foo f) {

    // Do subclass stuff pre-setting, if any

    super.setFoo(f);

    // Do subclass stuff post-setting, if any
}