在超类型中设置变量的正确方法

时间:2014-10-14 15:10:04

标签: java variables inheritance

我有一个抽象类Compartment,其中包含变量label tariff totalSeatsseatsAvailable,如下所示。我通过从子类super()的构造函数中调用FirstClassCompartment来设置这些变量。关于我的代码我几乎没有问题。

首先,这是使用超类构造函数设置变量的正确方法,或者我应该在超类中创建一个setter方法来设置这些变量。

其次,直接访问超类变量而不使用getter / setter方法是不好的编码。

最后,超类中变量seatsAvailable的值取决于子类中的变量seatsReserved,如seatsAvailable = totalSeats - seatsReserved。这可能导致代码维护或未来的灵活性问题吗?

public abstract class Compartment {

    protected final char label;
    protected final double tariff;
    protected final int totalSeats;
    protected int seatsAvailable;

    public Compartment(char label, double tariff, int totalSeats) {
        this.label = label;
        this.tariff = tariff;
        this.totalSeats = totalSeats;
    }

    public char getLabel() {
        return label;
    }

    public int getTotalSeats() {
        return totalSeats;
    }

    public void setSeatsAvailableLessByOne() {
        seatsAvailable--;
    }

    public abstract int getSeatsAvailable();

    public abstract double getTariff();

}


public class FirstClassCompartment extends Compartment {

    protected final int seatsReserved;

    public FirstClassCompartment(char label, double tariff, int totalSeats, int seatsReserved) {
        super(label, tariff, totalSeats);
        this.seatsReserved = seatsReserved;
        seatsAvailable = totalSeats - seatsReserved;
    }

    @Override
    public double getTariff() {
        return tariff + tariff * .13;
    }

    @Override
    public int getSeatsAvailable() {
        return seatsAvailable;
    }
}

3 个答案:

答案 0 :(得分:1)

第一个问题:这绝对是正确的方法。调用超类构造函数,并传递相关参数。

第二个问题:这在某种程度上是一种风格。最好不要让所有字段直接供所有字段使用,因此您不希望它们为public,但将它们提供给您自己的子类并不是灾难性的。但是,通过getter和setter使它们可用是非常合理的,当然如果你想让子类可以读取但不可写的字段,那么getter就是合适的。

第三个问题:这里没问题。超类是abstract,因此您希望子类实现填补一些空白。但由于seatsAvailable逻辑是如此简单(减法),你可能会想到完全摆脱seatsAvailable字段,而只是

@Override
public int getSeatsAvailable() {
    return totalSeats - seatsReserved;
}

这样,它会在飞行中计算,你不必担心让这个字段与其他字段保持同步。

答案 1 :(得分:0)

对我来说很好,我可能会将方法setSeatsAvailableLessByOne重命名为更有意义的内容,例如decrementSeatsAvailable,如果你想要它的话。

修改 你说seatsAvailable是多余的,你是对的。您可以将seatsReserved和派生值移动到超类tho'。在这些特定情况下,不太可能有其他方法来实现getSeatsAvailable方法,即使有,也可以覆盖它。

答案 2 :(得分:0)

我用“' package'来声明我的字段能见度。它是默认的可见性,可以通过inhered类和相同的包类访问它。当你进行单元测试时,它会有很大帮助,因为测试是在同一个包中编写的。

在我看来,不分青红皂白地使用getter / setter打破了封装。您可能会默认显示所有字段,可能不需要。

如果你的变量在构造函数中只设置了一次,那么它们应该是#final;#。

如果setter有一些逻辑,并且将来你可能需要覆盖它,然后使它可以覆盖,但在构造函数中使用可覆盖的方法不是一个好习惯。