我需要帮助创建子类,子类不会覆盖parent方法。我使用Registry对象来收集所有项目。
public class Registry {
private final Item[] items = new Item[100];
private int pos =0;
public Item[] getItems(){
return items;
}
public void addItem(Item item) {
items[pos] = item;
pos ++;
}
public void addItem(Item item, int nrTimes) {
for(int i = 0; i<nrTimes;i++){
items[pos] = item;
pos++;
}
}
public double totPrice(){
double total = 0.0;
for(int i = 0; i < items.length; i ++){
if(items[i] == null) break;
total += items[i].getNr(this);
}
return total;
}
public String toString() {
String result = "";
for(int i= 0; i < items.length;i++){
if (items[i] == null) break;
result = result + items[i].getName()+" $" + items[i].getNr(this) + " Sold by " + items[i].getName2()+ "\n";
}
return result;
}
}
public class Item {
private final String name;
private final String name2;
private final double nr1;
public Item (String name, String name2, double nr1) {
this.name = name; this.name2 = name2; this.nr1 = nr1;
}
public Item (Item obj) {
name = obj.name; name2 = obj.name2; nr1 = obj.nr1;
}
public double getNr(Registry reg) { return nr1;}
public final String getName() { return name;}
public final String getName2() { return name2;}
}
子类
public class ReducedItem extends Item {
private final Item obj = this;
private final double reduce; // in %
public ReducedItem (Item obj, double reduce) {
super(obj);
this.reduce = reduce/100;
}
public double getNr(Registry reg){
double nr;
nr = super.getNr(reg) - (super.getNr(reg)*reduce);
return nr;
}
}
这是我创建对象的主要部分
import java.util.*;
public class Main {
static Scanner scan = new Scanner(System.in);
public static void registerItems(Registry reg){
String name,seller;
double price;
int nrprod,discount;
scan.nextLine();
System.out.print("Product name: ");
name = scan.nextLine();
System.out.print("Seller: ");
seller = scan.nextLine();
System.out.print("Price: ");
price = scan.nextDouble();
System.out.print("How many: ");
nrprod = scan.nextInt();
System.out.print("Discount (enter 0 if no discount applies): ");
discount = scan.nextInt();
Item item = new Item(name,seller,price);
if(discount >0) {
ReducedItem redItem = new ReducedItem(item, discount);
if(nrprod == 1){
reg.addItem(redItem);
}else{
reg.addItem(redItem, nrprod);
}
}else{
if(nrprod == 1){
reg.addItem(item);
}else{
reg.addItem(item, nrprod);
}
}
}
public static void main(String[] args) {
System.out.println("Welcome");
System.out.println("What's your name?");
String customer = scan.nextLine();
System.out.println("Hi "+customer+". Please choose one of the following options:");
System.out.print("buy product (1) or checkout (0)");
Registry reg = new Registry();
int input = scan.nextInt();
while(input == 1){
registerItems(reg);
System.out.println("buy product (1) or checkout (0)");
input = scan.nextInt();
}
System.out.println(reg.toString());
System.out.println("Your total is " + reg.totPrice());
}
}
在registerItems中输入
Product name = Car
Seller = Jack
Price = 10000
how many =1
discount = 20
checkout = 0
输出
Car $8000 Sold by jack
Your total is 8000.0
现在该车的折扣率为20%
答案 0 :(得分:2)
您的错误位于Registry
课程的以下一行中。 (我收到了之前发布的源代码。)
public void addItem(Item item) {
items[pos] = new Item(item);
pos ++;
}
您无缘无故地创建了全新的Item
,即使客户想要添加ReducedItem
,您也可以通过替换{{}来有效删除折扣1}}用于ReducedItem
s并导致Item
重载从不使用。如果在调试器中逐步运行代码,您应该能够看到。
这一行应该只是ReducedItem.getNr
。
另请注意,您的items[pos++] = item;
课程有几个问题和隐藏的错误。例如,
Registry
方法重载; addItem(Item, int)
方法要求getNr
的实例不要将其用于任何内容; Registry
大于pos
时,您将会触发超出范围的索引; items.length
效率非常低,并且浪费了大量空间(例如Registry
),然后每次循环遍历所有100个空间,即使很少或没有添加任何项目。还有其他一些我不会涉及的问题,所以我建议您将代码与我在下面的建议进行比较,了解为什么它们会有所不同。
您提供的代码存在多个编译错误,并且令人困惑。相反,我试图理解你想要做的事情并重构代码,希望澄清一些事情,同时向你展示一些你应该考虑改进代码并简化代码的事情。
明白你需要调整我在这里写的内容。
我创建了一个new Item[100]
类来表示应用程序。它使用Example
来注册ItemRegistry
。 Item
接口由Item
(即RegularItem
没有折扣)和Item
实现,ItemDiscount
是Item
的一个示例{3}}
public interface Item {
String getName();
double getCost();
}
接口:RegularItem
这应该是直截了当的:基本上已经声明了一个类型。通常,您应该优先使用接口来指定新类型,因为它允许应用程序的其余部分依赖于合同协议(即规范)而不是实现细节(即班级)。这就是接口的用途。
警告:您不应该使用浮点类型来处理实际应用程序中的moneye。基本上这是由于舍入错误的累积会慢慢导致结果不正确。有关详细信息,请参阅Decorator Design Pattern。我在这里使用它是因为这是一个简单的玩具示例。
public class RegularItem implements Item {
private String name;
private double cost;
public RegularItem(String name, double cost) {
this.name = name;
this.cost = cost;
}
@Override
public String getName() {
return name;
}
@Override
public double getCost() {
return cost;
}
}
分类:ItemDiscount
这应该是不言自明的:具有名称及其相关成本的项目的简单实现。常规项目没有应用折扣。 ItemDiscount
课程开始变得更有趣。
// Decorator class
public class ItemDiscount implements Item {
private Item item;
private double discount;
public ItemDiscount(Item it, double amount) {
item = it;
discount = amount / 100.0; // e.g. 15/100 = 15%
}
@Override
public String getName() {
return item.getName();
}
@Override
public double getCost() {
return item.getCost() - (item.getCost() * discount);
}
}
类(装饰者)Item
它基本上包含了应用折扣的所有Item
需求,并在客户请求Item
的费用时返回折扣成本。这有几个好处:
ItemRegistry
,并且不知道哪些有或没有折扣。它不需要。还有更多,但我现在不会去那里。让我们跟进下面的ItemRegistry
:
import java.util.ArrayList;
import java.util.List;
public class ItemRegistry {
private List<Item> items = new ArrayList<Item>();
public ItemRegistry() {}
void registerItem(Item i) {
items.add(i);
}
double getTotalCost() {
double total = 0.0;
for(Item i : items)
total += i.getCost();
return total;
}
List<Item> getItems() {
return items;
}
}
等级ArrayList
请注意此简化版中的一些内容。
请注意,注册表 不知道它拥有的特定类型的项目 - 只是它们是项目。 (您不希望每次定义新类型的项目时都必须更新整个应用程序,或者更糟糕的是,强制那些需要维护您的代码的人来做这件事,对吗?)
使用注册表的客户端也不需要知道它是使用List
还是其他东西 - 只是它是Example
。这样可以提高空间效率并修复代码在添加100多个项目后会遇到的错误。
您可以使用下面的ItemRegistry
类来查看此内容,因为它使用了Example
:
public class Example {
public static void main(String[] args) {
ItemRegistry reg = new ItemRegistry();
reg.registerItem(new RegularItem("Toy Gun", 10));
reg.registerItem(new ItemDiscount(new RegularItem("Toy Car", 100), 10)); // apply 10% discount to Toy Car item
for(Item item : reg.getItems()) {
System.out.println("Name: " + item.getName());
System.out.println("Cost: " + item.getCost());
}
System.out.println("Total: " + reg.getTotalCost());
}
}
类(应用程序)Name: Toy Gun
Cost: 10.0
Name: Toy Car
Cost: 90.0
Total: 100.0
此示例应该使您更容易在调试器中逐步执行代码,以便您可以查看调用方法的方式以及覆盖实际如何工作。
{{1}}
并且是正确的:)
答案 1 :(得分:0)
这是我想象你正在寻找的一个工作范例。
public class J_crow {
public static void main(String... args) {
Item item = new Item("Name One", "Second Name", 42);
System.out.println(item);
Item reducedItem = new ReducedItem(item, 20);
System.out.println(reducedItem);
}
}
class Item {
private final String name;
private final String name2;
private final double nr1;
public Item(String name, String name2, double nr1) {
this.name = name;
this.name2 = name2;
this.nr1 = nr1;
}
public Item(Item obj) {
this(obj.getName(), obj.getName2(), obj.getNr());
}
public double getNr() {
return nr1;
}
@Override
public String toString() {
return String.format("I am an [%s], I cost [%f]", getClass().getCanonicalName(), getNr());
}
public String getName2() {
return name2;
}
public String getName() {
return name;
}
}
class ReducedItem extends Item {
private final double reduce; // in %
public ReducedItem(Item obj, double reduce) {
super(obj);
this.reduce = reduce;
}
@Override
public double getNr() {
return super.getNr() * (1 - (reduce / 100d));
}
}
输出:
I am an [Item], I cost [42.000000]
I am an [ReducedItem], I cost [33.600000]
答案 2 :(得分:0)
我真是太蠢了!我想出了我的问题
public void addItem(Item item) {
items[pos] = new Item(item);
pos ++;
}
public void addItem(Item item, int nrTimes) {
for(int i = 0; i<nrTimes;i++){
items[pos] = new Item(item);
pos++;
}
}
我每次创建一个新项目,我需要使用传递的参数
public void addItem(Item item) {
items[pos] = item;
pos ++;
}
public void addItem(Item item, int nrTimes) {
for(int i = 0; i<nrTimes;i++){
items[pos] = item;
pos++;
}
}
谢谢,我学到很多东西,阅读你的答案和评论