Java 代码的封装是否正确?我很迷惑

Is this proper encapsulation for this Java code? I am confused

涉及 Book class 的 Java 代码是否使用了正确的封装?我觉得如果我省略一些方法会简单很多,但我们需要其中的每个方法 [尤其是 setter 和 getter]。

这是第一个class:

public class Book
{
    private String title;
    private double price;
    private final double SALES_TAX=0.075;

    public String getTitle()
    {
        return title;
    }
    public void setTitle(String title)
    {
        this.title=title;
    }
    public double getPrice()
    {
        return price;
    }
    public void setPrice(double price)
    {
        this.price=price;
    }
    public double getSalesTax()
    {
        return SALES_TAX;
    }
    public double increasePrice(double incresePrice)
    {
        return incresePrice;
    }
    public double calculateSales(double sales)
    {
        return sales;
    }
}

第二个class:

public class BookDriver
{
    public static void main(String[] args)
    {
        Scanner keyboard=new Scanner(System.in);

        Book bookOne=new Book();
        Book bookTwo=new Book();

        bookOne.setTitle("Life of Pi");
        System.out.print("Enter number to buy of "+bookOne.getTitle()+": ");
        bookOne.setPrice(13.50*bookOne.calculateSales(keyboard.nextDouble()));
        bookOne.setPrice((bookOne.getPrice()*bookOne.getSalesTax())+bookOne.getPrice());
        System.out.print("Cost for "+bookOne.getTitle()+" $");
        System.out.printf("%.2f"+"\n",bookOne.getPrice());

        bookTwo.setTitle("Harry Potter: The Goblet Of Fire");
        System.out.print("Enter number to buy of "+bookTwo.getTitle()+": ");
        bookTwo.setPrice(22.00*bookTwo.calculateSales(keyboard.nextDouble()));
        bookTwo.setPrice((bookTwo.getPrice()*bookTwo.getSalesTax())+bookTwo.getPrice());
        System.out.print("Cost for "+bookTwo.getTitle()+" $");
        System.out.printf("%.2f"+"\n",bookTwo.getPrice());

        System.out.print("Enter percent increase of "+bookOne.getTitle()+": ");
        bookOne.setPrice((bookOne.getPrice()*bookOne.increasePrice(keyboard.nextDouble()))+bookOne.getPrice());
        System.out.printf("Cost of "+bookOne.getTitle()+": $"+"%.2f"+"\n",bookOne.getPrice());

        System.out.print("Enter percent increase of "+bookTwo.getTitle()+": ");
        bookTwo.setPrice((bookTwo.getPrice()*bookTwo.increasePrice(keyboard.nextDouble()))+bookTwo.getPrice());
        System.out.printf("Cost of "+bookTwo.getTitle()+": $"+"%.2f"+"\n",bookTwo.getPrice());

        keyboard.close();
    }
}

我知道这很多,所以我对回复的期望并不高,但任何事情都会有所帮助。谢谢!!

您不一定需要所有 setter。例如,假设一本书有一个标题,而且它不会改变,这可能是合理的。所以你可以让它成为最终的,省略 setter,并将它传递给构造函数。

另外,想想你是如何建模的。销售税是一本书的 属性 吗?我会说不是。

后两种方法意义不大。您只需 return 输入的内容即可。这样做:

public double increasePrice(double increase)
{
    price *= increase;
}
public double calculateSales(double sales)
{
    //return {your formula}
}

再来看封装点。您有一个 Class,它由属性和方法组成。封装背后的想法是,您希望 class 中的方法是更改​​属性值(状态)的唯一方法。可以这样想:如果程序中的某些其他代码想要更改其中一个属性的值,它自己无法完成,它必须请求它们所在的 class 上的方法来完成。这样,您就可以控制对属性的访问。

这是通过 getter 和 setter 方法实现的,您已经创建了一些方法。 getter 方法 returns 属性 的值和 setter 方法将其更改为新值。

1.

您的 getter 和 setter 方法直到 increasePrice() 都很好。您正在阻止访问 class 上的方法以外的属性。

2.

increasePrice() 只会吐出传入的内容。它不会更改任何属性的值,因此没有任何用处。如果您希望能够提高价格,您可以像这样更改方法:

  public void increasePrice(double amountOfPriceIncrease) {

    price += amountOfPriceIncrease;
     /* 
     price += amountOfPriceIncrease is the same as 
     price = price + amountOfPriceIncrease
     */

    }

3. 这条线有点麻烦。对于初学者来说,increasePrice() 除了吐出放入其中的内容外什么都不做,其次,一行中发生了很多事情,这使得它变得复杂且难以理解。

bookTwo.setPrice((bookTwo.getPrice()*bookTwo.increasePrice(keyboard.nextDouble()))+bookTwo.getPrice());

因为 class Book 所需的所有变量 title, price 都设置为私有,并且只能使用 get..() 使用该访问权限,并尽可能更改它只能使用 set..(some variable) 或影响其中一个字段的实例方法,它展示了 正确的封装 ,因此所有的获取和设置都是规范的。

但是,我在 BookDriver 中发现了几个错误,即 Book 字段的不当使用。 price 只能通过 setPriceincreasePrice 更改。 您还应该实施 getPriceAfterTax 来确定一本书的 after-tax 价格。 你买的书的总费用应该不涉及setPrice.

public double calculateSales(double sales) 有误。它除了 returns 返回 sales 什么都不做。 calculateSales 应该使用一个 int 变量计算购买书籍的总成本,并且您还改变了这些书籍的价格,这是不应该发生的。这就是你写乱码的原因,如摘录

bookTwo.setPrice(22.00*bookTwo.calculateSales(keyboard.nextDouble()));
bookTwo.setPrice((bookTwo.getPrice()*bookTwo.getSalesTax())+bookTwo.getPrice());

这避免了将 BOOK 对象的值更改为意外或不寻常的值和值组合的潜在情况。

此外,SALES_TAX 可以改为 public static final double,因为它假定永远不会改变,您可以简单地获得 SALE_TAX 而不需要 getSalesTax()