编辑:我回答这个问题是因为有很多学习编程的人都在问这个问题,而且大多数答案在技术上都很有能力,但如果你是新手,它们就不太容易理解。我们都是新手,所以我想我会尝试一个对新手更友好的答案。
两个主要是多态性和验证。即使它只是一个愚蠢的数据结构。
假设我们有这个简单的类:
public class Bottle {
public int amountOfWaterMl;
public int capacityMl;
}
一个非常简单的类,它包含多少液体,以及它的容量是多少(以毫升为单位)。
当我这样做时会发生什么:
Bottle bot = new Bottle();
bot.amountOfWaterMl = 1500;
bot.capacityMl = 1000;
好吧,你不会指望它会起作用,对吧?您希望进行某种健全性检查。更糟糕的是,如果我从未指定最大容量怎么办?哦,亲爱的,我们有问题。
但还有另一个问题。如果瓶子只是一种容器呢?如果我们有几个容器,所有容器都装有容量和数量的液体怎么办?如果我们可以创建一个接口,我们可以让程序的其余部分接受该接口,瓶子、塑料桶和各种东西都可以互换使用。那不是更好吗?由于接口需要方法,这也是一件好事。
我们最终会得到类似的东西:
public interface LiquidContainer {
public int getAmountMl();
public void setAmountMl(int amountMl);
public int getCapacityMl();
}
伟大的!现在我们只需将 Bottle 更改为:
public class Bottle extends LiquidContainer {
private int capacityMl;
private int amountFilledMl;
public Bottle(int capacityMl, int amountFilledMl) {
this.capacityMl = capacityMl;
this.amountFilledMl = amountFilledMl;
checkNotOverFlow();
}
public int getAmountMl() {
return amountFilledMl;
}
public void setAmountMl(int amountMl) {
this.amountFilled = amountMl;
checkNotOverFlow();
}
public int getCapacityMl() {
return capacityMl;
}
private void checkNotOverFlow() {
if(amountOfWaterMl > capacityMl) {
throw new BottleOverflowException();
}
}
我将把 BottleOverflowException 的定义作为练习留给读者。
现在请注意这是多么强大。我们现在可以通过接受 LiquidContainer 而不是 Bottle 来处理代码中的任何类型的容器。这些瓶子处理这类东西的方式各不相同。你可以让瓶子在它改变时将它们的状态写入磁盘,或者保存在 SQL 数据库或 GNU 知道的其他东西上的瓶子。
所有这些都可以有不同的方式来处理各种糟糕的事情。瓶子只是检查,如果它溢出它会抛出一个 RuntimeException。但这可能是错误的做法。(有一个关于错误处理的有用讨论,但我故意在这里保持非常简单。评论中的人可能会指出这种简单方法的缺陷。;))
是的,似乎我们从一个非常简单的想法转变为快速获得更好的答案。
另请注意,您不能更改瓶子的容量。它现在一成不变。您可以通过将 int 声明为 final 来执行此操作。但如果这是一个列表,您可以清空它,向其中添加新内容,等等。你不能限制接触内脏。
还有第三件事不是每个人都解决过:getter 和 setter 使用方法调用。这意味着它们看起来像其他地方的普通方法。DTO 和其他东西没有奇怪的特定语法,而是到处都有相同的东西。