2013-09-18 1 views
0

Ok У меня есть абстрактный класс «Order»:Loop через ArrayList, чтобы получить значения абстрактного метода

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-х классов, которые реализуют ее, которые похожи, за исключением, конечно, что они calculateBill по-разному в соответствии с налогом, тарифом и т. д.

сейчас я пытаюсь создать класс 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; 
} 

У меня возникли проблемы с методом getOrdersAbove, который должен вернуться и список массива порядков, клюв выше Валу. Будучи calcBill абстрактно и реализуется в каждом подклассе порядка, я должен просто назвать его правильным? Также, если это так, то не нужно OrderManager продлить заказ? Или просто быть в одном пакете позвольте мне назвать его методами? Или я все об этом ошибаюсь?

Спасибо за любую помощь!

+0

У вас на самом деле проблема? Ваш код кажется разумным - вы не хотите, чтобы OrderManager был подклассом Order. – John3136

+0

@ John3136 У меня возникли проблемы с циклом, но я думаю, что у меня это исправлено, но кто-то сказал, что мне нужны значения, которые нужно добавить к другому арраисту. Так что мне нужно объявить новый список в самом методе или он даже нужен? – user2745043

ответ

0

Будучи calcBill абстрактно и реализуется в каждом подклассе на заказ Я должен просто назвать это правильно?

Метод объявлен как public, вы сможете называть его Order экземплярами.

Также, если это так, то не следует заказывать OrderManager Order?

Спросите себя: это OrderManager заказ? Нет? Поэтому не заставляйте его распространять Order.

Или просто быть в одном пакете позвольте мне назвать его методами?

Опять же, этот метод является общедоступным, поэтому вы можете его вызвать из любого места, если у вас есть экземпляр, на который можно позвонить.

Так что в вашем for петле

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

При вызове calculateBill(), Java будет использовать late-binding (полиморфизм), чтобы решить фактическую реализацию метода использования.

+0

И я не вижу, как это трудно проверить, верно? – Marcelo

+1

@Marcelo Я согласен. Я хотел использовать такие понятия, как поздняя привязка и полиморфизм. –

+0

Ваш ответ довольно хороший, извините, что поставил этот комментарий здесь, хотел сочувствовать вам в том, что я думал об этом вопросе. – Marcelo

0

Ваш OrderManager не должен знать ничего о методе calculateBill подкласса Order.

Пока метод переопределен, вы можете быть уверены, что вам будет разрешено его вызывать, если он является общедоступным (или они находятся в одном пакете), поскольку вы не можете уменьшить видимость унаследованного метода.

Даже если Order является abstract и calculateBill в том классе, который не запрещает вам от вызова метода abstract. Единственное ограничение, которое применяется к классам abstract, заключается в том, что вы не можете создавать их экземпляр, как только у вас есть экземпляр (даже если его тип выполнения уже уже), то вы ни о чем не должны беспокоиться.

0

Будучи calcBill абстрактно и реализуется в каждом подклассе порядка, я должен просто назвать его правильным?

Java Runtime не очень волнует, что нет реализации метода calculateBill() в Order, просто Order «знает» (или же, может быть, лучше, «заявил») метод, называемый calculateBill(), который не принимает никаких аргументов и возвращает двойной - что он делает из вашей линии:

public abstract double calculateBill(); 

Обеспечение того, чтобы конкретные подклассы на самом деле реализовать абстрактный метод проверка осуществляется во время компиляции. Пока вы переопределили методы calculateBill() в подклассах (которые вам нужно будет сделать для компиляции кода), вы сможете его вызвать (из любого места, так как вы объявили его как public). Конкретная реализация calculateBill() - то есть, будет ли реализована реализация class Foo или class Bar - будет выбран для вас во время выполнения на основе конкретного экземпляра подкласса, на который вы его вызываете.

Также, если это так, тогда не следует заказывать OrderManager Order?

Нет. Я не понимаю, зачем это нужно. Кажется, это не имеет смысла. Если бы вы это сделали, вам пришлось бы выполнить конкретную реализацию calculateBill() внутри OrderManager, которая, похоже, не имеет смысла.

Или просто быть в одном пакете позвольте мне назвать его методами?

Публичные (нестатические) методы (которые calculateBill()) могут быть вызваны любым, у кого есть экземпляр класса, является ли вызывающий класс одним и тем же пакетом или нет.

Или я все об этом не так?

Вы, кажется, на правильном пути с абстрактными методами и реализацией в подклассах, а также обеспечение реализации по умолчанию различных методов в абстрактном классе (например, getPrice(), getLocation())

0

getOrdersAbove должен создать новый ArrayList для держите заказы выше val.

Вы добавляете выбранные заказы обратно в список, в котором вы выполняете итерацию, из-за чего итератор завершится с ошибкой.

Смежные вопросы