3

Object A instantiates Object B.

After the user interacts with Object B, I want to return back to Object A because Object A needs to use the user-determined results in Object B. User answers questions in Object B.

Is there anyway to do that without instantiating a new Object A and passing the results in a constructor? Or is that the best method? I'm curious because wouldn't instantiating two Objects of the same type be wasteful?

I don't want to use inner classes because in addition to keeping Object A short, I want to have other Objects be able to use the Assignment class.I am using GUI for user interface. //Object A== Main Page

//Homework 1
if(e.getSource()==task[0]){
        try {
            AssignmentA hw1= new AssignmentA("questions.txt", 0); //creates Assignment to do

        } catch (Exception e1) {
            // TODO Auto-generated catch block
            e1.printStackTrace();
        }
    }
    //Homework 2 Button
    else if(e.getSource()==task[1]){
        try {
            AssignmentA hw2= new AssignmentA("questions.txt",1);

        } catch (FileNotFoundException e1) {
            // TODO Auto-generated catch block
            e1.printStackTrace();
        }
    }

//Object B==Assignment A

-creates questions and answers

-user picks answers and Assignment A stores the grade for the assignment.

Here's the scenario: Object A is the Main Page that allows you to access different assignments through buttons and contains the overall grade after doing multiple assignments. Object B is an Assignment Class. When one button is clicked, the Object B is instantiated and the user has to answer questions. Once the user finishes the assignment, I want to be able to return to the Object A/Main Page with a new overall grade without creating a new Object A.

I don't want to use an inner class because I have other pages that want to use the Assignment Class as well.

snoopy
  • 121
  • 1
  • 2
  • 9
  • I am not sure if I understand your question correctly, but I suspect that you may be interested in inner classes. – Pshemo Jul 08 '15 at 16:14
  • I am trying not to use inner classes because Object A can instantiate Objects B,C,D,E,F,G... so I was trying to keep minimize the number of lines needed. – snoopy Jul 08 '15 at 16:17
  • 3
    This is a very vaguely-worded question. You've got answers and suggestions all over the place ... can you be more specific about your use case? Is this in Swing? A web application? What is the relationship between A and B (aside from A creating B)? A bit of code, even pseudo-code, would be very helpful. – dcsohl Jul 08 '15 at 16:22

4 Answers4

1

Use a callback, something like:

interface Doer {
    void doSomething(SomeClass data);
}

class B {
    private Doer doer;
    public B(Doer doer) {
        this.doer = doer;
    }
    void run() {
        if (something)
            doer.doSomething(something);
    }
}

class A implements Doer {
    void doSomething(SomeClass data) {
        // whatever
    }

    void callB() {
        B b = new B(this);
        b.run();
    }
 }
Bohemian
  • 412,405
  • 93
  • 575
  • 722
1

Some ideas:

Here's the scenario: Object A is the Main Page that allows you to access different assignments through buttons and contains the overall grade after doing multiple assignments. Object B is an Assignment Class. When one button is clicked, the Object B is instantiated and the user has to answer questions. Once the user finishes the assignment, I want to be able to return to the Object A/Main Page with a new overall grade without creating a new Object A.

  • Have your main class, A hold a collection of the B's that the user has interacted with, such as an ArrayList<B>. Whenever a new B object is created and displayed, add it to the above list, which will allow A to iterate through the list whenever needed allowing it to query each B as to their states.
  • Give B a status state such an enum BState that can have possible values of INITIALIZED, STARTED, COMPLETED, and give B a BState variable with getters and setters. This way A can iterate through the list and see what has been completed or not.
  • The visualized part of B, its' "view" should be based towards creating a JPanel. This way you can display it any number of ways, such as in its own JDialog, in a JOptionPane or my favorite, swapped inside of A using a CardLayout.
  • If A needs to track or respond if B has completed an assignment, then make the BState variable a "bound property" by giving B a SwingPropertyStateSupport field, and an addPropertyChangeListener(...) method that adds these listeners to the support object. Then when B's BState changes, it can notify any and all listeners.

You ask:

Is there anyway to do that without instantiating a new Object A and passing the results in a constructor? Or is that the best method? I'm curious because wouldn't instantiating two Objects of the same type be wasteful?

  • Whatever you do, do not create another "Object A". Don't even consider doing this as it will create a new and distinct object A, one whose state will have no effect on the original "object A".
Hovercraft Full Of Eels
  • 283,665
  • 25
  • 256
  • 373
  • This sounds like the information I am looking for. I'll read into the SwingPropertyStateSupport field and enum types. Sorry for the vagueness and thanks for the help. – snoopy Jul 08 '15 at 17:00
  • @alison: You're welcome and thanks for improving the question. Note that Swing components already come with default property change support as well as `addPropertyChangeListener(...)` and the corresponding remove methods, making this easier for you. [For example](http://stackoverflow.com/a/9346946/522444). – Hovercraft Full Of Eels Jul 08 '15 at 17:01
0

When object A instantiates object B it can pass itself as one of the parameters to the constructor.

When Object B is done it task - it can call a method on Object A telling it that it can continue.

class A {

     void objectBisDone() {
         //....
     }

     void createObjB() {
         B b = new B(this); // <-- pass itself to B's constructor
         b.run();
     }
}

class B {

    A myA;

    B(A a) {myA = a;} // save A as a member

    void run() {
        // ...
        // and when B is done
        myA.objectBisDone();

    }
}
Nir Alfasi
  • 53,191
  • 11
  • 86
  • 129
0

In OOP, any information that one abstraction shall make public, should be through public getter methods. I mean: Provide in class B as many get* methods as necessary, so that object A can invoke them.

Little Santi
  • 8,563
  • 2
  • 18
  • 46