Build a Fluent Interface in Java in Less Than 5 Minutes
Tags: java, beginners, tutorial, oop
Published: 2019-01-31 22:56:14

[(Skip to the good part!)](#good-part)

## Building a Basic Class

Building classes in Java is _**EASY!**_ All you need is a class declaration inside a file with the same name as the class (but with a `.java` at the end of it). A minimal example would be something like

```java
// MyClassName.java

// class must be public and created in a file called <classname>.java
public class MyClassName {
  // no other code needed!
}
```

You can put the above code into a file named `MyClassName.java` and load it in the `jshell` with the `/open` command:

```java
jshell> /open MyClassName.java

jshell> MyClassName j = new MyClassName()
j ==> MyClassName@6c3708b3
```

...that's it! Because `MyClassName` (like all classes) extends `Object`,  we get some built-in methods if we type `j.` in the `jshell` and hit the `tab` key:

```java
jshell> j.
equals(       getClass()    hashCode()    notify()      notifyAll()   toString()    wait(         
```

## Building a Custom Constructor

Of course, this isn't very exciting. Often, we'll create our own _constructors_ to give objects a certain _state_ (instance variables, etc.). Let's add a few private variables which we can set via a constructor:

```java
// MyClassName2.java

// class must be public and created in a file called <classname>.java
public class MyClassName2 {

  private int instanceInt;
  private double instanceDouble;
  private String instanceString;

  public MyClassName2 (int myInt, double myDouble, String myString) {
    this.instanceInt = myInt;
    this.instanceDouble = myDouble;
    this.instanceString = myString;
  }
}
```

Now if we try to create an instance of `MyClassName2` in the `jshell` using the default no-argument constructor, we get an error:

```java
jshell> /open MyClassName2.java

jshell> MyClassName2 j2 = new MyClassName2()
|  Error:
|  constructor MyClassName2 in class MyClassName2 cannot be applied to given types;
|    required: int,double,java.lang.String
|    found: no arguments
|    reason: actual and formal argument lists differ in length
|  MyClassName2 j2 = new MyClassName2();
|                    ^----------------^
```

...this is because the default zero-argument constructor is _only_ provided by Java if no other constructors have been defined. Since we defined our three-argument (`int`, `double`, `String`) constructor above, that's the only one we have access to at the moment. So let's create a `MyClassName2` object:

```java
jshell> MyClassName2 j2 = new MyClassName2(42, 3.14, "bonjour le monde!")
j2 ==> MyClassName2@6c3708b3
```

...great! It worked!

## Getters and Setters

### Getters

To get anything _out of_ this object, though, we'll need some _getters_. Let's add those:

```java
// MyClassName3.java

// class must be public and created in a file called <classname>.java
public class MyClassName3 {

  private int instanceInt;
  private double instanceDouble;
  private String instanceString;

  public MyClassName3 (int myInt, double myDouble, String myString) {
    this.instanceInt = myInt;
    this.instanceDouble = myDouble;
    this.instanceString = myString;
  }

  // getters are methods, so they have a return type
  public int getMyInt() {
    return this.instanceInt;
  }

  // we use 'this' to refer to the object calling the method
  public double getMyDouble() {
    return this.instanceDouble;
  }

  // ('this' isn't strictly necessary here, but it can make the code clearer)
  public String getMyString() {
    return this.instanceString;
  }

}
```

Now, we can create an object with some parameters and extract those parameters later!

```java
jshell> /open MyClassName3.java

jshell> MyClassName3 j3 = new MyClassName3(17, 1.618, "hola mundo!")
j3 ==> MyClassName3@335eadca

jshell> j3.getMyInt()
$5 ==> 17

jshell> j3.getMyDouble()
$6 ==> 1.618

jshell> j3.getMyString()
$7 ==> "hola mundo!"
```

### Setters

_Setters_ let us _change the state_ of an object. In other words, they let us change the values held in an objects instance variables. Setters are just methods that take a parameter and set an instance variable equal to that parameter. Let's add some:

```java
// class must be public and created in a file called <classname>.java
public class MyClassName4 {

  private int instanceInt;
  private double instanceDouble;
  private String instanceString;

  public MyClassName4 (int myInt, double myDouble, String myString) {
    this.instanceInt = myInt;
    this.instanceDouble = myDouble;
    this.instanceString = myString;
  }

  // getters are methods, so they have a return type
  public int getMyInt() {
    return this.instanceInt;
  }

  // we use 'this' to refer to the object calling the method
  public double getMyDouble() {
    return this.instanceDouble;
  }

  // ('this' isn't strictly necessary here, but it can make the code clearer)
  public String getMyString() {
    return this.instanceString;
  }

  public void setMyInt (int newInt) {
    this.instanceInt = newInt;
  }

  public boolean setMyDouble (double newDouble) {
    this.instanceDouble = newDouble;
    return true;
  }

  public String setMyString (String newString) {
    this.instanceString = newString;
    return this.instanceString;
  }

}
```

Setters should describe (in the method name) what instance variable they're setting, and they usually only take a single parameter (which will be assigned to the instance variable indicated by the name of the method).

But the philosophy on return values from setters falls into several camps:
- If your setter _will always, without fail_ successfully set the value, some people will return `void` from a setter method.
- If there's a chance your setter could fail, you could also return `boolean`, with `true` indicating that the instance variable was successfully assigned the provided value
- Or, you could just return the instance variable in question at the end of the method. If it's successfully been changed, the return value will reflect that.

These three philosophies have been applied, in order, to the setters given above. Let's see them in action:

```java
jshell> MyClassName4 j4 = new MyClassName4(19, 2.71828, "hello world!")
j4 ==> MyClassName4@72b6cbcc

jshell> j4.getMyInt(); j4.setMyInt(23); j4.getMyInt()
$10 ==> 19
$12 ==> 23

jshell> j4.getMyDouble(); j4.setMyDouble(1.2345); j4.getMyDouble()
$13 ==> 2.71828
$14 ==> true
$15 ==> 1.2345

jshell> j4.getMyString(); j4.setMyString("aloha honua"); j4.getMyString()
$16 ==> "hello world!"
$17 ==> "aloha honua"
$18 ==> "aloha honua"
```

We can see (in the non-existent step `$11`) that `setMyInt()` returns void. No value is shown in the `jshell`.

`setMyDouble()` returns `true`, though, as the value was successfully changed. We can see that in the before (`$13`) and after (`$15`) steps.

Finally, `setMyString()` returns the value of `this.instanceString` at the end of the method. Since the instance variable has successfully been changed, the return value reflects that.

<a name="good-part"></a>
### Fluent Interfaces

But we can return any sort of value we want from a method! There's no reason why we couldn't return `-14` or `"r2349jp3giohtnr"` or `null` from any one of those setters. There's no restriction to the kind of value we can return.

__So what happens if we return `this`?__

Let's try it! Let's change our `setMyInt()` method to return `this`, which is a reference to the object which is calling the method (in this case, the `setMyInt()` method):

```java
  public MyClassName5 setMyInt (int newInt) {
    this.instanceInt = newInt;
    return this;
  }
```

I removed the rest of the class for brevity, but it should be the same as `MyClassName4` (with `4` changed to `5` everywhere). So how does this method work? Well, it returns the object which called the method, which in this case is a `MyClassName5` object, so we need to make that the return value. Let's try this method and see what happens:

```java
jshell> MyClassName5 j5 = new MyClassName5(0, 0.0, "zero")
j5 ==> MyClassName5@5d76b067

jshell> j5.setMyInt(-1)
$21 ==> MyClassName5@5d76b067
```

Look at the return values from these two statements in the `jshell` -- they're the same! They both return the object `MyClassName5@5d76b067`. If that's true, shouldn't we be able to call another method on the value returned from `setMyInt()`? Let's try it!

```java
jshell> j5.getMyInt()
$22 ==> -1

jshell> j5.setMyInt(2).setMyDouble(2.2)
$23 ==> true

jshell> j5.getMyInt(); j5.getMyDouble()
$24 ==> 2
$25 ==> 2.2
```

Look what happened there! Chaining the methods worked! But the return value (in `$23`) was `true` because `setMyDouble()` still returns a `boolean`. If we change all of our setters to return a `MyClassName5` object, we should be able to chain them together in any order!

Let's make a `MyClassName6` with setters that return `MyClassName6` objects, similar to what we did above. Again, I'll only write the setters here to save space:

```java
  public MyClassName6 setMyInt (int newInt) {
    this.instanceInt = newInt;
    return this;
  }

  public MyClassName6 setMyDouble (double newDouble) {
    this.instanceDouble = newDouble;
    return this;
  }

  public MyClassName6 setMyString (String newString) {
    this.instanceString = newString;
    return this;
  }
```

Let's try it!

```java
jshell> MyClassName6 j6 = new MyClassName6(6, 6.6, "six")
j6 ==> MyClassName6@131276c2

jshell> j6.setMyString("seven").setMyDouble(77.77).setMyInt(777)
$28 ==> MyClassName6@131276c2

jshell> j6.getMyString(); j6.getMyDouble(); j6.getMyInt()
$29 ==> "seven"
$30 ==> 77.77
$31 ==> 777
```

That's it! All we had to do to be able to chain methods together was to return `this`. Returning `this` lets us call method after method in series, and all of those methods will be applied to the same (original) object!

An idea which is quite similar to fluent interfaces is the _Builder pattern_, which works almost the same as the setters above, but that is a topic for another article.

Be sure to let me know in the comments if you have any questions or critiques!