当子类在构造函数中初始化时,我是否应该在超类的声明中保留字段初始化



根据这个问题的答案,鉴于我有一个在声明上初始化了字段的类,当我扩展该类并需要子类具有不同的默认值时,我该怎么办?

我是否应该在子类的构造函数中分配新的默认值,并将赋值保留在超类的声明中?

public class Bird {
    private boolean flight = true;
}
public class Penguin extends Bird {
    public Penguin() {
        flight = false;
    }
}

还是应该重构,以便两个类都初始化构造函数中的字段?

从这个问题的答案来看,似乎没有显着的技术差异,所以这是一个关于语义的问题。

首先是两种情况之间的差异。

对于不可变属性(最严格的 - 很好 - 大小写):

public class Bird {
    public final boolean flight;
    public Bird() {
        this(true);
    }
    protected Bird(boolean flight) {
        this.flight = flight();
    }
}
public class Penguin extends Bird {
    public Penguin() {
        super(false);
    }
}

对于更自由、更动态的用法:

public class Bird {
    protected boolean flight = true;
    public boolean hasFligth() {
        return flight;
    }
}
public class Penguin extends Bird {
    public Penguin() {
        flight = false;
    }
}

然而,flight可能被认为不是每个鸟类/企鹅对象的属性:它是类的属性(企鹅、鸵鸟等)。一种策略模式,或:

Map<Class<Bird>, Boolean>
Set<Class<Bird>> // better

位于另一侧,在舱位飞行中。

如果你为扩展设计你的超类,并希望允许某个字段可以初始化为另一个值,你可能应该通过构造函数参数公开它:

public class Bird {
    private final boolean flight = true;
    public Bird() {
        this(true);
    }
    public Bird(boolean flight) {
        this.fligjt = flight;
    }
    public boolean isFlight() {
        return this.flight;
    }
}
public class Penguin extends Bird {
    public Penguin() {
        super(false);
    }
}

最新更新