Программно объявить переменную для общего метода (без использования массива)

Я только изучаю Java, но мой вопрос связан как с Java, так и с общим.

Моя ситуация такова: у меня есть метод, который я хотел бы использовать обычно несколькими классами через наследование. Внутри блока метода мне нужно объявить переменную вызывающего класса, создать из нее объекты, которые размещены в ArrayList‹> («массив») вызывающего класса, и отправить вывод через ObjectOutputStream («выход») в сериализованный файл.

У меня есть следующие классы:

CustomerInternalFrame.java, который поддерживает «массив» сериализованных Customer.java, используя ArrayList типа Customer.

ContractorInternalFrame.java, который поддерживает «массив» сериализованных Contractor.java, используя ArrayList типа Contractor.

VendorInternalFrame.java, который поддерживает «массив» сериализованных Vendor.java, используя ArrayList типа Vendor.

В каждом из этих классов InternalFrame у меня есть следующий метод addRecords (замените «Клиент» соответствующим классом: «Клиент», «Подрядчик» или «Поставщик»):

private void addRecords() {

  // object to be written to the file
  Customer record;

  // loop until end of array
  for (Customer element : array) {

     // check for closed streamer and invalid entries
     try {

        // create a new object from current fields
        record = new Customer(
           element.getName(),
           element.getLastName(),
           element.getAddress1(),
           element.getAddress2(),
           element.getCity(),
           element.getState(),
           element.getZip(),
           element.getPhone(),
           element.getCell());

        // write new record
        output.writeObject(record);
     } // end try
     ... (catch blocks)
   } // end for
} // end method

Я много думал и долго искал способ программно изменить слово «Клиент» в приведенном выше, чтобы я мог объявить единственный метод (или класс) addRecords() и заставить каждый из трех классов InternalFrame использовать его, не имея дублировать код. Я, конечно, не могу заменить слово «Клиент» на «Объект» во всех случаях, потому что «Объект» не имеет моих методов getName(), getAddress1() и т. д. Я также не могу заменить «Клиент» на «Объект()». ", по той же причине. (Другими словами, использование массивов — обычное решение — в данном случае не работает, потому что мне пришлось бы использовать массив суперкласса, а затем приводить его к понижению, а приведение к понижению требует объявления первоначально названного класса в первую очередь. Так что в данном случае массив — это просто порочный круг.)

Я понимаю, что наличие трех отдельных методов addRecords() позволяет мне изменять любые поля, которые я записываю в соответствующем файле, поскольку у Заказчика, Подрядчика и Продавца вполне могут быть разные наборы полей. Но у меня есть и другие похожие ситуации, когда вещи, которые я делаю в коде, идентичны, но вызываются разными классами (например, похожими обработчиками событий), и было бы неплохо знать, если что-то вроде этого вообще можно сделать.

Итак, есть ли способ изменить тип переменной, в том числе путем передачи ее в метод или конструктор, чтобы несколько классов могли использовать один и тот же код для создания объектов этих конкретных классов?


person user2487795    schedule 14.06.2013    source источник
comment
Пожалуйста, сформулируйте вопрос покороче   -  person nachokk    schedule 15.06.2013
comment
Это будет работать только в том случае, если три класса имеют одинаковые методы, в противном случае они не полиморфны, поэтому вы не знаете, какой вызов метода для установки/получения каждого атрибута в каждом типе, возможно, вы можете передать массив с каждым параметром и у каждого класса есть общий метод, такой как setAttributes, который считывает массив и устанавливает каждое значение   -  person DGomez    schedule 15.06.2013
comment
Вместо new Customer(...) почему бы не element.clone()?   -  person Eric    schedule 15.06.2013


Ответы (1)


Сделайте свой базовый класс универсальным, например:

public abstract class InternalFrame<T> {

    protected abstract Collection<? extends T> getElements();

    protected abstract Serializable getRecord(final T t);

    public void serialize(final File file) {
        try (final ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(file))) {
            for(final T t : getElements()) {
                oos.writeObject(getRecord(t));
            }
        } catch (IOException ex) {
            //handle
        }
    }
}

И тогда в вашем расширяющемся классе вам просто нужно реализовать методы abstract

public class CustomerFrame extends InternalFrame<Customer> {

    @Override
    protected Collection<? extends Customer> getElements() {
        return array;
    }

    @Override
    protected Serializable getRecord(Customer element) {
       return new Customer(
       element.getName(),
       element.getLastName(),
       element.getAddress1(),
       element.getAddress2(),
       element.getCity(),
       element.getState(),
       element.getZip(),
       element.getPhone(),
       element.getCell());
    }

}

И вы бы вызвали метод serialize(final File file) для записи записей в File.

person Boris the Spider    schedule 15.06.2013