子类和超类

时间:2015-10-14 21:22:56

标签: java inheritance constructor subclass

我需要帮助创建子类,子类不会覆盖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%

3 个答案:

答案 0 :(得分:2)

Bug解释

您的错误位于Registry课程的以下一行中。 (我收到了之前发布的源代码。)

public void addItem(Item item) {
    items[pos] = new Item(item);
    pos ++;
}

您无缘无故地创建了全新的Item,即使客户想要添加ReducedItem,您也可以通过替换{{}来有效删除折扣1}}用于ReducedItem s并导致Item重载从不使用。如果在调试器中逐步运行代码,您应该能够看到。

这一行应该只是ReducedItem.getNr

另请注意,您的items[pos++] = item;课程有几个问题和隐藏的错误。例如,

  1. 此错误也出现在不必要的Registry方法重载;
  2. 命名错误的addItem(Item, int)方法要求getNr的实例不要将其用于任何内容;
  3. 在您的注册表中添加足够的项目,当Registry大于pos时,您将会触发超出范围的索引;
  4. items.length效率非常低,并且浪费了大量空间(例如Registry),然后每次循环遍历所有100个空间,即使很少或没有添加任何项目。
  5. 还有其他一些我不会涉及的问题,所以我建议您将代码与我在下面的建议进行比较,了解为什么它们会有所不同。

    代码重新设计

    您提供的代码存在多个编译错误,并且令人困惑。相反,我试图理解你想要做的事情并重构代码,希望澄清一些事情,同时向你展示一些你应该考虑改进代码并简化代码的事情。

    明白你需要调整我在这里写的内容。

    摘要

    我创建了一个new Item[100]类来表示应用程序。它使用Example来注册ItemRegistryItem 接口Item(即RegularItem没有折扣)和Item实现,ItemDiscountItem的一个示例{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的费用时返回折扣成本。这有几个好处:

    1. 客户只看到ItemRegistry,并且不知道哪些有或没有折扣。它不需要。
    2. 您可以在同一项目上申请任意数量的折扣(例如,有5张优惠券的客户?没问题!)
    3. 您的应用程序更易于理解和维护
    4. 还有更多,但我现在不会去那里。让我们跟进下面的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

      请注意此简化版中的一些内容。

      1. 课程不需要处理折扣或非折扣的“特殊情况”。 (请记住有5张优惠券的顾客?此处不需要更改!)
      2. 该类使用 interfaces 而不是类进行通信,这些类是应该保持封装的实现细节。
      3. 请注意,注册表 不知道它拥有的特定类型的项目 - 只是它们是项目。 (您不希望每次定义新类型的项目时都必须更新整个应用程序,或者更糟糕的是,强制那些需要维护您的代码的人来做这件事,对吗?)

        使用注册表的客户端也不需要知道它是使用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++;
    }
} 

谢谢,我学到很多东西,阅读你的答案和评论