0

OK、抽象クラス「Order」があります。

public abstract class Order {
protected String location;
protected double price;

public Order(double price, String location){
    this.price = price;
    this.location = location;
}
public abstract double calculateBill();

public String getLocation() {
    return location;
}
public double getPrice() {
    return price;
}
public abstract String printOrder(String format);   
}

私はまた、それを実装する3つのクラスを持っています.

今、それらを管理するために OrderManager クラスを作成しようとしています。これは私がこれまでに持っているものです

public class OrderManager {
private ArrayList<Order> orders;

public OrderManager() {     
}   
public OrderManager(ArrayList<Order> orders) {
    this.orders = orders;   
}   
public void addOrder(Order o) {
    orders.add(o);
}   
public ArrayList<Order> getOrdersAbove(double val) {
    for (Order o : orders) {
        double bill = o.calculateBill();
        if (bill > val)
            orders.add(o);
    }
    return orders;
}

請求額が val を超えている注文の配列リストを返すべき getOrdersAbove メソッドに問題があります。calculateBill であることは抽象的であり、注文の各サブクラスに実装されているので、正しいと言えますか? また、その場合、OrderManager は Order を拡張すべきではありませんか? または、同じパッケージにいるだけで、そのメソッドを呼び出すことができますか? それとも、私はそれについてすべて間違っていますか?

助けてくれてありがとう!

4

4 に答える 4

0

calculateBill であることは抽象的であり、注文の各サブクラスに実装されているので、正しいと言えますか?

メソッドは として宣言されているため、インスタンスpublicで呼び出すことができOrderます。

また、その場合、OrderManager は Order を拡張すべきではありませんか?

自問してみてください: OrderManager は Order ですか? いいえ?したがって、延長しないでくださいOrder

または、同じパッケージにいるだけで、そのメソッドを呼び出すことができますか?

繰り返しになりますが、このメソッドはパブリックであるため、呼び出すインスタンスがあればどこからでも呼び出すことができます。

だからあなたのforループで

public ArrayList<Order> getOrdersAbove(double val) {
    for (Order o : orders) {
        double bill = o.calculateBill();
        // do logic
    }
}

を呼び出すとcalculateBill()、Java は遅延バインディング(ポリモーフィズム) を使用して、使用するメソッドの実際の実装を解決します。

于 2013-09-18T21:55:53.930 に答える
0

calculateBill であることは抽象的であり、注文の各サブクラスに実装されているので、正しいと言えますか?

calculateBill()Java ランタイムは、 にメソッドの実装がないことをあまり気にしません。引数を受け入れず、double を返すメソッドが呼び出されたOrderことをOrder「知っている」(または、もっと良いのは、「宣言されている」)だけです。calculateBill()あなたのラインの:

public abstract double calculateBill();

具体的なサブクラスが実際に抽象メソッドを実装していることを確認することは、コンパイル時に行われるチェックです。サブクラスのメソッドをオーバーライドしている限りcalculateBill()(コードをコンパイルするためにオーバーライドする必要があります)、それを呼び出すことができます ( として宣言したため、どこからでもpublic)。特定の実装calculateBill()(それが の実装であろうとclass Fooの実装class Barであろうと) は、呼び出している特定のサブクラス インスタンスに基づいて、実行時に選択されます。

また、その場合、OrderManager は Order を拡張すべきではありませんか?

いいえ、なぜそうすべきなのかわかりません。あまり意味がないようです。もしそうなら、同様にあまり意味がないように見えるcalculateBill()insideの具体的な実装が必要になるでしょう。OrderManager

または、同じパッケージにいるだけで、そのメソッドを呼び出すことができますか?

パブリック (非静的) メソッド (つまりcalculateBill()) は、呼び出し元のクラスが同じパッケージ内にあるかどうかに関係なく、クラスのインスタンスを持っている人なら誰でも呼び出すことができます。

それとも、私はそれについてすべて間違っていますか?

サブクラスの抽象メソッドと実装、および抽象クラスのさまざまなメソッドのデフォルト実装を提供することで、正しい軌道に乗っているようです(例getPrice(), getLocation():)

于 2013-09-18T22:02:31.987 に答える
0

のサブクラスのメソッドOrderManagerについて何も知る必要はありません。calculateBillOrder

メソッドがオーバーライドされている限り、継承されたメソッドの可視性を低下させることはできないため、メソッドが公開されている (または同じパッケージにある) 場合は、メソッドを呼び出すことができることを確認できます。

OrderisabstractcalculateBillisabstractがそのクラスにあり、メソッドの呼び出しを禁止していない場合でも。クラスに適用される唯一の制限はabstract、それらをインスタンス化できないことです。インスタンスを取得したら (実行時の型がより狭い場合でも)、何も心配する必要はありません。

于 2013-09-18T21:58:52.603 に答える
0

getOrdersAbove は、val を超える注文を保持するために新しい ArrayList を作成する必要があります。

選択した注文を反復処理中のリストに追加し直すと、反復子が失敗します。

于 2013-09-18T22:19:08.987 に答える