0

我有两个课程:公寓和建筑。公寓类:

public class Apartment {
    private String familyName;
    private int rent;
    private boolean isRented;
}

Building 类有一个 Apartment 数组和一个 numOfApartments 变量,它指示该建筑物有多少个公寓,还有一个 FINAL 变量,它指示一栋建筑物中公寓的最大数量。

private Apartment[] apartments;
private int numOfApartments;
private final int MAX_APARTMENTS=20;

public Building() {
    this.apartments=new Apartment[MAX_APARTMENTS];
    this.numOfApartments=0;
}

现在我想制作一种方法,将公寓的租金提高一个作为参数的金额:

public void raiseRent(int amount) {
    for (int i=0; i<numOfApartments; i++) {
        apartments[i].setRent(apartments[i].getRent() + amount);
    }
}

addAppartment 方法:

public boolean addApartment(Apartment a){ //adds an appartment to the building if
                                           //there's enough space in the array.
        if (this.numOfApartments<this.MAX_APARTMENTS)
        {
            this.apartments[this.numOfApartments]=new Apartment(a);
            this.numOfApartments++;
            return true;
        }
        return false;
    }

公寓类字符串 ToS​​tring 方法:

public String toString()
{
    if (this.isRented) //if the apartment is rented, prints:
    {
        return "Apartment rent: " + this.rent + ". rented to " + this.familyName + " family.";
    }
    else
        return "Apartment rent: " + this.rent  + ". not rented yet.";
}

主要是:

String familyName; int rent;
System.out.println("enter family name and rent by this order");
familyName=scan.next();
rent=scan.nextInt();

Apartment a=new Apartment(familyName,rent);  //build new apartment object.
Building b=new Building();
System.out.println(b.addApartment(a));
b.raiseRent(200); //initiate the raiseRent method.

这里的一切都有效,但是当我写这个时:

 System.out.println(a);

租金显示为旧租金,而不是更新后的租金。当我写这个时:

System.out.println(b.apartments[0]);

有用。

为什么当我写 System.out.println(a); 它不工作?

谢谢你的回答。

4

2 回答 2

1

问题出在您的addApartment方法中:您不是将传入的对象添加到数组中,而是添加一个通过调用复制构造函数Apartment创建的全新对象。new这打破了a您传入的变量与数组索引为零的元素之间的连接apartments,从而解释了打印值的差异。

您在 中的复制语义addApartment实际上是一件好事:它使您免于以后出现不寻常的别名,因为实现不再依赖于调用者来传递不同的对象。将代码更改为

apartments[this.numOfApartments] = a; // No copy

产生问题,因为Apartmentmutable。考虑这个调用序列:

Apartment a = new Apartment();
for (int i = 100 ; i <= 1000 ; i += 100) {
    a.setRent(i);
    building.addApartment(a);
}

预计会有 10 套公寓,租金在 100 到 1000 之间。但是,如果进行无副本更改,您最终会得到十个相同的公寓,所有公寓的租金都设置为 1000。这是因为在引擎盖下,apartment数组中的所有十个项目都将引用同一个Apartment对象 - 您在for循环之前创建的那个. 这会导致很多麻烦,因此最好保留复制代码,并知道租金增加应该检查建筑物内的对象,而不是您传递给addApartment方法的对象。

于 2013-02-02T15:15:07.797 回答
1

在你的

public boolean addApartment(Apartment a)方法:

this.apartments[this.numOfApartments]=new Apartment(a);

创建一个似乎是从现有公寓建造的新公寓。这是一个副本。

提高租金后,

Apartment a=new Apartment(familyName,rent); //build new apartment object.

你传递给

b.addApartment(a)

不会有更新的租金。这是因为 Java 是按值传递的。int它是new Apartment您的 Building集合包含的“新” Apartment[],即使您从现有集合中设置它 ( this.rent = other.rent)

于 2013-02-02T15:15:18.740 回答