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
只能通过 setPrice
或 increasePrice
更改。
您还应该实施 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()
。
涉及 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
只能通过 setPrice
或 increasePrice
更改。
您还应该实施 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()
。