views:

184

answers:

6

Currently I can think of only three good reasons to return this in a (public) method, namely:

  1. (mmyers) when implementing fluent interfaces, e.g.

    public class X
    {
      ...
      public X enableValidation()
      {
        setValidation(true);
        return this;
      }
      ...
    }
    
  2. (Jon Skeet) for identity conversions, e.g.

    public class X
    {
      ...
      public X toX()
      {
        return this;
      }
      ...
    }
    
  3. (Dave Ray) implementing a clone() or copy() method on an immutable object, e.g.

    @Immutable
    public class X
    {
      ...
      public X copy()
      {
        return this;
      }
      ...
    }
    

Are there any other useful scenarios in an object-oriented language in which you would return this or self from a method?

+2  A: 

String.toString() :)

On a more serious note, there are similar "convert to [x]" scenarios where it's okay to just return "this"... but I can't think of very many other situations.

Jon Skeet
Ok, good answer, identity conversion.
eljenso
+2  A: 

Any implementation of a clone() or copy() method on an immutable object.

Dave Ray
Agree, good answer.
eljenso
+4  A: 

If you are creating chaining operations (however this might not be very OOP'ish - Law of Demeter, etc).

Example (not that it makes a lot of sense):

public class X 
{
   public X Add(int i) 
   { 
      this.Value += i; 
      return this;
   }

   public X Subtract(int i) 
   {
      this.Value -= i;
      return this;
   }

   public int Value 
   {
      get;
      set;
   }
}

new X().Add(4).Subtract(5).Value;
veggerby
Fluent interface, already covered in the question. Still, good that you agree that this is a valid and useful reason for returning this.
eljenso
Ahh, sorry ;) Note to self: read complete question next time
veggerby
A: 

C++ does this all the time to allow cascading operators.

for example the << operator always returns itself (ostream) so that you can cascade the calls in such a way:


std::cout << "call 1" << "call2" << std::endl;

The only language which I believe this cascading effect is popular is C++.

mmattax
I guess this falls in the category of fluent interfaces (already covered in the question) which is more common than I thought.
eljenso
A: 
VonC
I know, not *exactly* an answer to your question, but I find this pattern for "fluent" hierarchy interesting.
VonC
A: 

Take the following implementation.

public interface Monitorable {
   public Statistics getStatistics();
}

public interface MonitorManager {
   public Monitorable getMonitorable();
}

class MonitorableService implements Monitorable, MonitorManager {
   public Monitorable getMonitorable() {
      return this;
   }
}

// Meanwhile somwhere else...
MonitorManager manager = getMonitorManagerFromSomewhere();
Monitorable monitorable = manager.getMonitorable();

I admit this is rather contrived, but the overal pattern/message should be clear.

Here I do not need to know the MonitorManager is implemented by the Application class. Nor do I need to know that Monitorable is implemented by Application.

Here polymorphism is used to encapsulate the implementation details of Application. Which is not a public class. This is a very common pattern, and can be seen in a wide variety of projects.

ng
First of all, thanks for responding. I can read your code more clearly now, but I still don't get some things. Where is the Application class? Why is the Monitor interface declared but not used? Is the only function of MonitorManager to return a Monitorable?
eljenso
I think that what you express here can be solved by using the correct types. An instance of MonitorableService can be declared as Monitorable or MonitorManager or MonitorableService (which includes both) depending on the context.
eljenso
Yes, the contract of MonitorManager has been achieved with a single object, although several are in play. The implementation details are hidden from the user, this could be implemented in other ways, however there is often very useful to realise the contract in this way, as many frameworks do.
ng
Again you say that this is a common pattern. You've even said that it's a critical requirement of most OO systems. So maybe you could show me one or two projects where this pattern is used?
eljenso
Well I said the examples I gave were fundamental, this pattern was included with passing an object to a method using "this" as you may remember, a much more useful use of this than "this.field". I think the pattern here is obvious, and useful. You will see examples it in many frameworks.
ng