tags:

views:

118

answers:

9

If I instantiate an object in a main class, say:

SomeObject aRef = new SomeObject();

Then I instantiate another object from the main class, say:

AnotherObject xRef = new AnotherObject();

How can the instance of AnotherObject make use of the aRef reference to access the methods in SomeObject? (To use the same instance of SomeObject)

+5  A: 

Why not instantiate AnotherObject with a reference to the original SomeObject ?

e.g.

SomeObject obj = new SomeObject();
AnotherObject obj2 = new AnotherObject(obj);

and AnotherObject would look like:

// final used to avoid misreferencing variables and enforcing immutability
private final SomeObject obj;

public AnotherObject(final SomeObject obj) {
   this.obj = obj;
}

so AnotherObject has a reference to the previously created SomeObject. It can then use this reference to call methods on. If the original object is not required outside the scope of AnotherObject, then create it inside AnotherObject and enforce encapsulation that way.

Brian Agnew
A: 
xRef.SetSomeObject(aRef);

where SetSomeObject has a signature like

public void SetSomeObject(SomeObject obj)
{
    obj.DoStuff();
}

and is a member function of the type AnotherObject.

dkackman
It is very strange to ask someone to do stuff which a caller could easily do itself. Especially in a method with a name which implies "setter" (you know, when you assign a given reference or object to one of the private fields)
Dmitry
true. I was more illustrating how to pass a reference into the target object. poor choice of name on my part.
dkackman
A: 

The strategy design pattern and Decorator design pattern are 2 different ways you can do this.

For instance you can have:

class AnotherObject
{
    private SomeObject mySomeObject;
    public AnotherObject(SomeObject mySomeObject)
    {
        this.mySomeObject = mySomeObject;
    }

    function doSomethingUsingStrategy()
    {
        mySomeObject.doItTheMySomeObjectWay();
    }

    function setMySomeObject(SomeObject mySomeObject)
    {
        this.mySomeObject = mySomeObject;
    }
}

Then later on, you can use a different strategy:

myAnotherObject.setMySomeObject(new ExtendsSomeObject);
myAnotherObject.doSomethingUsingStrategy()
Zak
+1  A: 

I think what you are asking is a question about scope. You're asking how can xRef use aRef during execution? The answer is that the aRef reference needs to be passed into the xRef object when it's being instantiated

xRef = new AnotherObject(aRef)

or after the instantiation you could have

xRef.setSomeObject(aRef)
MattC
yes it's a question about scope. for example the main method creates an instance of a class and uses its mutator methods, then creates an instance of another class which also needs to use those mutator methods.
Kari
A: 

Could AnotherObject have a member or property that has a type of SomeObject? That would be another way to handle this too.

So, if there was a "SomeObjectMember" member of the AnotherObject class:

xRef.SomeObjectMember = aRef;
JB King
A: 

You need to provide the reference to aRef to instances of AnotherObject either in the constructor: AnotherObject xRef = new AnotherObject(aRef) or using setter methods: xRex.setSomeObject(aRef). In this case AnotherObject needs to have an instance variable to store aRef that can be used internally like:

class AnotherObject {
    SomeObject aRef;
    public AnotherObject(SomeObject aRef) {
        this.aRef = aRef;
    }
    public void doSomethingWithSomeObject() {
        aRef.doSomething();
    }
}

You could also pass instances of SomeObject to methods on AnotherObject that require them like xRef.doSomethingWithSomeObject(aRef).

class AnotherObject {
    public void doSomethingWithSomeObject(SomeObject aRef) {
        aRef.doSomething();
    }
}
Tendayi Mawushe
A: 

There are a bunch of ways to do it (as pointed out by others). You really want to think about your object structure though...

Perhaps your main method shouldn't even be instantiating aRef, perhaps it should be instantiated inside xRef's constructor (this is the case where xRef tends to be a "part" of the functionality of aRef.

If aRef can have multiple instances at some point you may not want to store it off at all, you may want to pass it in whenever an xRef method uses it.

This is where you need to consider your object model at a business logic level. What are the relationships between the objects, etc.

(My guess is that you want xRef to instantiate aRef and keep the reference itself, then if your "main" really needed to talk with aRef it could either ask xRef to forward the message or ask xRef for it's instance of aRef.)

Bill K
thanks. the logic is this: the main method creates an instance of a class and sets data in it using its mutator methods, then at some point it creates an instance of another class which also needs to use those mutator methods
Kari
What do the two objects represent? Dogs? Trees? Databases? Operands for some calculation? What is the relationship between the two different objects. They aren't quite peers because one uses the other without the other knowing about the first. Why do you have to create both of the objects in main? Is there some information in main that is not available elsewhere?
Bill K
I know it seems strange, but answering those questions and thinking about relationships like this is what makes your OO model usable as it grows and morphs, otherwise objects are kind of useless.
Bill K
Thanks for your help! Yes it's probably a design issue since I'm quite new to this. Basically I have a class which contains info about a node (temperature info). The main class accepts info from the user so it creates an instance of the temperature class to use its mutator methods. Then at some point a new Thread is created (this would be an instance of another class) which also needs access to the temperature object.
Kari
If the thread is only processing info from the temperature class, it belongs inside the temperature class (as an inner/anonymous inner class). This keeps all your info and logic together in the same class. You can also have your temperature class itself implement runnable, but this is frowned upon because it allows other classes access to your "Run" method when they don't need it (it gives other classes too much information about the implementation of your class)--but I often just have my class implement Runnable as a first pass anyway.
Bill K
Thanks Bill, I will review my object structure.
Kari
A: 

You have to pass the ref and then do something with it.

class AnotherObject {
     SomeObject someObject;

     public void setSomeObject( SomeObject some ) {
         this.someObject = some;
     }

     public void doSomethingWithSomeObject() {
         this.someObject.someMethod();
     }

     ..... rest of your code 
 }

That way you can use it like this in the main method

 public static void main( String [] args ) {
     SomeObject xRef = new SomeObject();
     AnotherObject aRef = new AnotherObject();
     // pass the ref... 
     aRef.setSomeObject( xRef );
     // use it
     aRef.doSomethingWithSomeObject();
 }

Is that what you need?

OscarRyz
yes that makes sense. so basically the scope of an object reference is always limited to the class that creates it?
Kari
Mmhh you can say that. To be available from other context you could pass the reference like in the sample. Also, you can have *class* attributes, which are visible class wide. But that's another topic. You can think of them as "global" variables. One example is the "out" attribute of the System class, like in `System.out.println`?
OscarRyz
+1  A: 

The answer to his question is making the first class a static class.

Programmer
what I did was set the fields of the first class as static, and make the accessor and mutator methods public. that way i could create two instances of the same class but the data would be the same. but I thought there would be a better way of doing it!
Kari