0

アパートと建物の 2 つのクラスがあります。アパートメントクラス:

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

Building クラスには、Apartment 配列と、建物にあるアパートの数を示す numOfApartments 変数と、1 つの建物内のアパートの最大数を示す 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;
    }

アパートメント クラスの文字列の 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.";
}

主なものは次のとおりです。

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作成された新しいオブジェクトを追加します。これにより、渡された変数と配列のインデックス 0 の要素とのnew間の接続が切断され、出力される値の違いが説明されます。aapartments

にあるコピー セマンティックは、addApartment実際には良いことです。実装が呼び出し元に依存して個別のオブジェクトを渡す必要がなくなるため、後で異常なエイリアシングを回避できます。コードを次のように変更します

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

mutableApartmentであるため、問題が発生します。次の呼び出しシーケンスを検討してください。

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

10 室のアパートがあり、100 から 1000 の家賃が追加されると予想されます。ただし、コピーなしの変更を行うと、家賃がすべて 1000 に設定された 10 の同一のアパートができあがります。これは、apartment配列内の 10 個の項目すべてが内部で同じ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 ApartmentApartment[]this.rent = other.rent

于 2013-02-02T15:15:18.740 に答える