Java 子类与超类
我需要创建子类的帮助,子类不会覆盖父类方法。我使用注册表对象来收集所有项目Java 子类与超类,java,inheritance,constructor,subclass,Java,Inheritance,Constructor,Subclass,我需要创建子类的帮助,子类不会覆盖父类方法。我使用注册表对象来收集所有项目 公共类注册表{ 私有最终项[]项=新项[100]; 私人int pos=0; 公共项[]getItems(){ 退货项目; } 公共无效附加项(项目){ 项目[pos]=项目; pos++; } 公共无效附加项(项,整数次){ 对于(int i=0;i0){ ReducedItem redItem=新的ReducedItem(项目、折扣); 如果(nrprod==1){ 注册附加项(redItem); }否则{ 注册附加
公共类注册表{
私有最终项[]项=新项[100];
私人int pos=0;
公共项[]getItems(){
退货项目;
}
公共无效附加项(项目){
项目[pos]=项目;
pos++;
}
公共无效附加项(项,整数次){
对于(int i=0;i0){
ReducedItem redItem=新的ReducedItem(项目、折扣);
如果(nrprod==1){
注册附加项(redItem);
}否则{
注册附加条款(redItem,nrprod);
}
}否则{
如果(nrprod==1){
注册附加项(项目);
}否则{
注册增补项(项目,nrprod);
}
}
}
公共静态void main(字符串[]args){
System.out.println(“欢迎”);
System.out.println(“你叫什么名字?”);
字符串customer=scan.nextLine();
System.out.println(“Hi”+客户+”。请选择以下选项之一:”;
系统输出打印(“购买产品(1)或结帐(0)”;
Registry reg=新注册表();
int input=scan.nextInt();
while(输入=1){
登记册(reg);
System.out.println(“购买产品(1)或结帐(0)”;
输入=scan.nextInt();
}
System.out.println(reg.toString());
System.out.println(“您的总数为”+reg.totPrice());
}
}
注册表项中的输入
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%的折扣。这是一个我想你正在寻找的工作示例
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]
Bug解释道
您的bug位于注册表
类中的以下一组行中。(我得到了你之前发布的源代码。)
您无缘无故地创建了一个全新的项目
,即使客户希望添加ReducedItem
,因此您通过为项目
s替换ReducedItem
s并导致永远不使用ReducedItem.getNr
重载,有效地消除了折扣。如果在调试器中逐步运行代码,您应该能够看到这一点
此行应该是items[pos++]=item代码>
还要注意,您的注册表
类存在一些问题和隐藏的bug。比如说,
这个bug也存在于不必要的addItem(Item,int)
方法重载中李>
名称不正确的getNr
方法期望注册表的一个实例不使用它做任何事情李>
在注册表中添加足够的项,当pos
大于项时,您将遇到索引超出范围的异常李>
注册表
效率非常低,并且浪费了大量空间(例如新项目[100]
),然后每次都循环使用所有100个项目,即使添加的项目很少或没有
还有其他几个问题我不会讨论,所以我建议您将代码与下面的建议进行比较,并了解它们的不同之处
代码重新设计
您提供的代码有几个编译错误,使用起来很混乱。相反,我试着去理解你想要做的事情,并重构了代码,希望能澄清一些事情,同时,向你展示一些你应该考虑的事情来改进你的代码并简化它。
请理解,您需要修改我在这里写的内容
总结
我创建了一个示例
类来表示应用程序。它使用anItemRegistry
来注册Item
s。项目
接口由项目
(即没有折扣的项目
)和项目折扣
实现,这是一个示例
项目
界面:
这应该很简单:基本上已经声明了一个类型。通常,您应该优先使用接口来指定新类型,因为它允许应用程序的其余部分依赖于合同协议(即规范),而不是实现细节(即类)。这就是接口的用途
警告:您不应该在实际应用程序中使用浮点类型来处理Money。基本上,这是由于舍入误差的累积,这将慢慢导致结果不正确。有关更多信息,请参阅。我在这里使用它,因为这是一个简单的玩具示例
regulatem
Class:
这应该是不言自明的:一个带有名称及其相关成本的项目的简单实现。普通商品没有折扣。使用ItemDiscount
类,事情开始变得更加有趣
项目折扣
类(装饰师)
它基本上包装了需要应用折扣的项目
,并在客户请求项目
的成本时返回折扣成本。这有几个优点:
客户只看到项目
s,不知道哪些项目有折扣或没有折扣。不需要这样
您可以在同一商品上申请任意数量的折扣(例如,有5张折扣券的客户?没问题!)
您的应用程序更易于理解和维护
还有很多,但我现在不去了。让我们继续关注下面的ItemRegistry
:
ItemRegistry
Class
此示例将使您能够更轻松地在调试器中一步一步地遵循代码,这样您就可以看到方法是如何被调用的,以及重写实际上是如何工作的
程序输出:
这是正确的:)我真蠢!我解决了我的问题
public void addItem(项目){
物料[pos]=新物料(物料);
pos++;
}
公共无效附加项(项,整数次){
对于(int i=0;i请发布完整代码。可以尝试添加@Ov
I am an [Item], I cost [42.000000]
I am an [ReducedItem], I cost [33.600000]
public void addItem(Item item) {
items[pos] = new Item(item);
pos ++;
}
public interface Item {
String getName();
double getCost();
}
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;
}
}
// 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);
}
}
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;
}
}
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
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++;
}
}