StackOverflow путаница - PullRequest
       10

StackOverflow путаница

0 голосов
/ 06 февраля 2011

Я новичок в Java, и у меня очень запутанная проблема с ошибками StackOverflow / возможностью доступа к файлам между классами.Я понимаю, что основная причина, скорее всего, в том, что у меня есть какой-то рекурсивный вызов, но синтаксис его устранения ускользает от меня.Я думаю, что это как-то связано с тем, как классы связаны через одно расширение другого, но, если класс InputScreen не расширяет ViewController, я не могу получить доступ к нужным там методам.Я поместил код высокого уровня ниже (создание программы для отслеживания пробега бензина).

Цель этого состоит в том, чтобы иметь возможность открыть xml-файл с некоторыми историческими данными о пробеге (с помощью метода doOpenAsXML ()), а затем разрешить пользователю добавлять данные в некоторые текстовые поля (определенные в классе InputScreen)Добавьте другую точку данных в ArrayList, а затем сохраните, используя метод doSaveAsXML.

У кого-нибудь есть идеи, как заставить это работать?Спасибо !!!


// Simple main just opens a ViewController window
public class MpgTracking {
    public static void main(String[] args) {
        ViewController cl = new ViewController();
        cl.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        cl.setVisible(true);
    } // end main
}</p>

<p>public class ViewController extends JFrame {</p>

<pre><code>    // the array list that I want to fill using the historical data
    public ArrayList<MpgRecord> hist; 

    public ViewController() {
         doOpenAsXML();  // open historical data, put into 'hist'
         InputScreen home = new InputScreen ();
    }

    public void doSaveAsXML() {
    // ...long block to save in correct xml format
    }

    public void doOpenAsXML() {
    // ...long block to open in correct xml format
    }

}

открытый класс InputScreen расширяет операторы ViewController {// для определения экрана с текстовыми полями и операторы // кнопки «Сохранить» // для созданияпрослушиватель операторов кнопки Сохранить // для добавления в историю ArrayList, открытый в методе ViewController doSaveAsXML ();}

Ответы [ 3 ]

1 голос
/ 07 февраля 2011

Кажется, это основная причина вашей проблемы:

но, если класс InputScreen не расширяет ViewController, я не могу получить доступ к нужным там методам.

Чтобы получить доступ к (нестатическим) методам в другом классе, вам нужен объект этого класса. В вашем случае InputStream должен был бы иметь объект ViewController, а не быть объектом ViewController. (В тех же строках ViewController не должен быть JFrame, но иметь единицу - хотя здесь это не создает проблем.)

Если вы измените это, вы не получите свой цикл конструктора.

public class ViewController {

    ...

    public ViewController() {
         doOpenAsXML();  // open historical data, put into 'hist'
         InputScreen home = new InputScreen (this); // give myself to our new InputScreen.
         // do something with home
    }

    public void doSaveAsXML() {
    // ...long block to save in correct xml format
    }

    public void doOpenAsXML() {
    // ...long block to open in correct xml format
    }


}

public class InputScreen {

    private ViewController controller;

    public InputScreen(ViewController contr) {
       this.controller = contr;
    }


    void someMethod() {
        // statements to define a screen with text fields and a 'Save' button
        // statements to create a listener on the Save button
        // statements to add to the ArrayList hist, opened in the ViewController method
        controller.doSaveAsXML();
    }
}
1 голос
/ 06 февраля 2011

Вы говорите, что InputScreen расширяет ViewController?Кажется, что это был бы бесконечный рекурсивный цикл прямо в конструкторе.Также

public ViewController() {
     doOpenAsXML();  // open historical data, put into 'hist'
     InputScreen home = new InputScreen ();
}

ничего не делает.Вы создаете новый InputScreen, устанавливаете его в переменную home, которая сразу же получает GCed, как только конструктор завершает работу.

0 голосов
/ 24 марта 2011

Краткие ответы: Состав по наследству . Программа против интерфейсов . Принцип наименьших привилегий . Ролевые интерфейсы .

Я бы посоветовал вам сделать гугл на них после прочтения моего поста;)

Во-первых, вам не нужно InputStream наследовать от ViewController, поскольку VieController.doSaveAsXML() является общедоступным.

Даже если бы он имел частную | защищенную | видимость пакета, мы не должны использовать наследование только для доступа к методу какого-то другого класса, который нам не виден. Наследование предназначено для наследования , уточнения или расширения , а не для доступа к методам.

Вы всегда можете передать контроллер как тип аргумента в ваш поток ввода. Если ваш входной поток должен получить доступ ко всем методам в контроллере, передайте контроллер как есть (или попросите контроллер реализовать интерфейс со всеми методами в нем).

Первое, на что нужно обратить внимание , это то, что вашему InputStream действительно не нужен доступ к контроллеру. Ему нужен только доступ к чему-то, что может выполнять для него функции file opening - ему нужно file opener.

Вторым важным моментом, на который следует обратить внимание , является то, что контроллеру (как правило) также не нужно знать, как открывать файлы. Контроллер обычно является организатором или оркестратором (из-за отсутствия лучшего слова). Таким образом, ему не нужно открывать файл (или реализовывать саму логику открытия файла). Контроллеру просто нужна ссылка на file opener , Как и input stream, controller нужно просто делегировать file opening logic file opener.

Другими словами:

  1. ваш входной поток должен иметь доступ к открывателю файлов
  2. ваш контроллер также должен только иметь доступ к открывателю файлов
  3. ваш контроллер инициализирует ваш входной поток, и так, он должен передать ему открыватель файлов во время инициализация
  4. из-за вышеизложенного контроллер сам должен получить, создается или быть настроен с Сам инструмент для открытия файлов.
  5. поскольку средство открытия файлов является внешним по отношению к и поток, и контроллер, Средство открытия файлов должно быть интерфейс (который может быть реализован с помощью средства для открытия XML-файлов или любого другого в этом отношении.)

псевдокод Java:

public interface FileOpener
{
  public void doOpen();
}

public class XMLOpener implements FileOpener
{
  public void doOpen(){ ... do xml specific file opening ... }
}

public interface Stream
{
   /** inits stream with controller     
    **/
   public void init(FileOpener FileOpener);
   public void kickIt();
}

public interface Controller 
{
   // defines other methods implemented by actual interfaces.
   public void kickIt();
}

public class ViewController implements Controller 
{
   private Stream stream;
   private FileOpener opener;

   public ViewController( final Stream stream. final FileOpener opener )
   {
     this.stream = stream;
     this.opener = opener;

     this.stream.init(this.opener);
   }


   public void kickIt(){ stream.kickIt() );
}

public class InputStream implements Stream
{
   private FileOpener opener;

   public InputStream()
   {
   }

   public Stream init(final FileOpener opener )
   {
     this.opener = opener;
   }

   public void kickIt()
   {
     this.opener.doOpen();
   }
}

....

Controller controller = new ViewController( 
      new InputStream(), 
      new XMLOpener() );

Идете ли вы до конца, заставляя все работать против обработчиков интерфейсов, это дизайнерское решение, которое мы должны принимать с каждым проектом. Но этот подход (или что-то вдохновленное этим), как правило, путь. Так гораздо сложнее (но не невозможно) придумать циклические зависимости, и когда они возникают, они являются вопросом конфигурации, а не внутренней проблемой вашей объектной модели.

Надеюсь, это поможет.

...