简体   繁体   English

Java对象:方法不能打印

[英]Java Objects: Method doesn't print as it should

I have two classes: Apartments and Building. 我有两个班:公寓和建筑。 The Apartment class: 公寓类:

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

The Building class has an Apartment array, and a numOfApartments variable which indicates how many apartments the building has, and also a FINAL variable who indicates the max number for apartments in one building. 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;
}

Now I want to make a method which raises the rent for an apartment by an amount which is taken as parameter: 现在我想制作一个方法来提高公寓的租金,作为参数:

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

the addAppartment method: 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;
    }

The apartment class string ToString method: 公寓类字符串ToString方法:

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.";
}

The main is: 主要是:

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.

Everything here works, but when I write this: 这里的一切都有效,但是当我写这篇文章时:

 System.out.println(a);

The rent is shown as the old rent, not the updated one. 租金显示为旧租金,而不是更新的租金。 When I write this: 当我这样写:

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

It works. 有用。

Why when I write System.out.println(a); 为什么我写System.out.println(a); it doesn't work? 它不起作用?

Thank you for the answer. 谢谢你的回答。

The problem is in your addApartment method: rather than adding the Apartment object passed in to the array, you add a brand-new object created with new by calling a copy constructor. 问题是在你的addApartment方法:而不是添加Apartment传递到数组对象,您添加与创建一个全新的对象new通过调用拷贝构造函数。 This breaks the connection between the variable called a that you passed in and the element at index zero of the apartments array, explaining the difference in printed values. 这破坏了变量之间的连接称为a您在过去,在索引零元素apartments阵列,说明在印值的差。

The copy semantic that you have in the addApartment is actually a good thing: it saves you from unusual aliasing later on, because the implementation is no longer dependent on the callers to pass distinct objects. 你在addApartment拥有的复制语义实际上是一件好事:它addApartment以后出现异常的别名,因为实现不再依赖于调用者来传递不同的对象。 Changing the code to 将代码更改为

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

creates problems, because Apartment is mutable . 创造问题,因为Apartment可变的 Consider this call sequence: 考虑这个调用顺序:

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

One would expect ten apartments, with rents 100 to 1000 to be added. 人们可以期待10套公寓,租金增加100到1000。 With a no-copy change, however, you would end up with ten identical apartments, all with rent set to 1000. This is because under the hood all ten items in the apartment array would reference the same Apartment object - the one you created before the for loop. 然而,通过无副本更改,您将最终得到十个相同的公寓,所有租金都设置为1000.这是因为在引擎盖下, apartment阵列中的所有十个项目都将引用相同的Apartment对象 - 您之前创建的对象for循环。 This causes numerous headaches down the road, so it is better to keep the copying code in place, and know that rent increases should be checked on the objects inside the building, not on the objects that you passed into the addApartment method. 这会导致很多麻烦,所以最好保持复制代码到位,并且知道应该在建筑物内的对象上检查租金增加,而不是在传递给addApartment方法的对象上。

In your 在你的

public boolean addApartment(Apartment a) method: public boolean addApartment(Apartment a)方法:

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

Creates a new apartment which appears to be constructed from an existing apartment. 创建一个新公寓,似乎是从现有的公寓建造。 This is a copy. 这是一份副本。

After you raise the rent, the 提高租金后,

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

That you passed in to 你传入的那个

b.addApartment(a)

Will not have an updated rent. 没有更新的租金。 This is because Java is pass-by-value. 这是因为Java是按值传递的。 It's a "new" int in the new Apartment your Building Apartment[] collection contains, even if you set it from an existing one ( this.rent = other.rent ) 它是new Apartment your Building Apartment[]集合中包含的“new” int ,即使你是从现有的this.rent = other.rent设置它( this.rent = other.rent

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM