Scala can mix in reusable code into different classes while Java can only inherit from one base class

As an example, let us say you have one Java class "Person" and another Java class "Product" which both needs to be Observable (i.e. be the "Subject" in the GoF Observer pattern). You then might choose to extend the Observable as a base class. In that case, you would be able to reuse code in that base class. However, now assume that these Person and Product classes need to extend other (and different) base classes, which can neither extend Observable. Then you need to implement some amount of duplication in your Java code (in Person and Product Java classes), which will be illustrated below. Though, with Scala implementations, you would instead be able use the concept of 'traits' which allows you to "mix in" a reusable implementation into these classes.

/**
 * The actual content of this class is not relevant, but the important thing is
 * that it represents the situation when some base class is needed, and
 * you therefore can not extend from some other base class such as the Observable.
 */
public class PersonBaseClassWithImplementationIrrelevantForTheExample {
    // ... irrelevant (see comment above)    
}

// Base-interface for Person and Product:
import java.util.Observer;
public interface ObservableAdder { // not perfect interface name, but I wanted a name distinct from the class Observable
    void addObserver(Observer observer);
}

public interface Person extends ObservableAdder {
    void setName(String name);
}

/**
 * This class can not extend Observable, since it is needed to extend some other base class, and therefore
 * it is necessary to use object composition, which can not be completely reused, but some duplication is needed.
 */
public class PersonImplementedInJava extends PersonBaseClassWithImplementationIrrelevantForTheExample implements Person {
    // The bold code below is duplicated in classes PersonImplementedInJava and ProductImplementedInJava
    private final Observable observable = new ObservableReusable();
    /**
     * This method is defined in the interface Person (through its base interface)
     */
    public void addObserver(Observer observer) {
        observable.addObserver(observer);
    }

    // The above kind of code, i.e. declaring the variable and the implementation of an interface method is hard to avoid
    // in Java, when it can not be inherited from a base class, since the base class needs to be some other class    

    private String name = "";

    /**
     * This method is defined in the interface Person
     */
    public void setName(String name) {
        this.name = name;
        observable.notifyObservers("(Java implementation) Person name changed. New name: " + name);
    }
}


/**
 * The purpose of this class is to invoke the protected method 'setChanged',
 * which is needed for the invocation of 'notifyObservers' to have any effect.
 * Of course, it could have been instantiated as an anonymous class
 * instead, but that would create some duplication, so therefore it
 * was defined as a reusable class instead (reused from Person and Product classes) 
 */
public class ObservableReusable
    extends Observable // subclassing Observable to be able to invoke its protected method 'setChanged' 
{
    // The above class name would not be considered nice in a normal application,
    // but here in this example code, the name reflects the purpose of being a reusable
    // class, but nevertheless some other code needs to be duplicated in the client Java code,
    // i.e. the code that uses this class is duplicated from different Java classes
    // which are inheriting code from other base classes.
    // Scala, however can also reuse the client code for this class through a so called 'trait'.
    @Override
    public void notifyObservers(Object arg) {
        setChanged(); // protected method which needs to be invoked for the 'notifyObservers' below to have any effect 
        super.notifyObservers(arg);
    }
}

public interface Product extends ObservableAdder {
    void setPrice(Double price);
}


/**
 * The actual content of this class is not relevant, but the important thing is
 * that it represents the situation when some base class is needed, and
 * you therefore can not extend from some other base class such as the Observable. 
 */
public class ProductBaseClassWithImplementationIrrelevantForTheExample {
    // ... irrelevant (see comment above)
}

/**
 * This class can not extend Observable, since it is needed to extend some other base class, and therefore
 * it is necessary to use object composition, which can not be completely reused, but some duplication is needed.
 */
public class ProductImplementedInJava extends ProductBaseClassWithImplementationIrrelevantForTheExample implements Product {
    // The bold code below is duplicated in classes PersonImplementedInJava and ProductImplementedInJava
    private final Observable observable = new ObservableReusable();
    /**
     * This method is defined in the interface Product (through its base interface)
     */
    public void addObserver(Observer observer) {
        observable.addObserver(observer);
    }

    // The above kind of code, i.e. declaring the variable and the implementation of an interface method is hard to avoid
    // in Java, when it can not be inherited from a base class, since the base class needs to be some other class

    private Double price = null;
    public void setPrice(Double price) {
        this.price = price;
        observable.notifyObservers("(Java implementation) Product price changed. New price: " + price);
    }
}


Below is some alternative Scala code with Person and Product implementations which behave in the same way as the above Java implementations of those interfaces.

The difference that you should pay attention to, is that the Scala Person and Product classes below do not duplicate as much code as in the above Java implementations of the same interface, i.e. the bold code in PersonImplementedInJava and ProductImplementedInJava is not duplicated in the Scala classes below, but that implementation is instead reused through a "mixin" of the 'trait' ObservableTrait.

import java.util.{Observer, Observable}
trait ObservableTrait {

  // The class below ('ObservableReusable') could be reused from Java classes, 
  // but the declaration and instantiation was duplicated in different Java classes
  // while the code here in this Scala 'trait' can be reused from different Scala classes
  private val observable = new ObservableReusable();

  // The method below was also duplicated in different Java classes,
  // but in Scala, the implementation of this trait can be inherited from multiple
  // Scala classes, even though those classes inherit from other base classes
  def addObserver(observer: Observer): Unit = {
    observable.addObserver(observer)
  }

  // The method below can be used directly by Scala classes using the trait,
  // i.e. those Scala classes do not need to refer the 'observable'
  // as the Java classes did, and if the Java classes would have wanted to
  // avoid it, by defining a protected method as below, it would not
  // have been possible because of the single-inheritance in Java,
  // and that inheritance was already used for other base classes
  // than Observable related code. 
  protected def notifyObservers(observer: Object): Unit = {
    observable.notifyObservers(observer)
  }
}

import java.util.Observer
/**
 * This class does not need to duplicate the code in ObservableTrait, i.e. the implementation
 * code can be inherited even though the class has another base class.
 */
class PersonImplementedInScala
  extends PersonBaseClassWithImplementationIrrelevantForTheExample // Java base class  
  with Person // Java interface defining the methods 'setName' and 'addObserver'
  with ObservableTrait // provides e.g. the implementation of the method 'addObserver'
{
  private var name = "";
  def setName(name: String) = {
    this.name = name;
    notifyObservers("(Scala implementation) Person name changed. New name: " + name)

    // the implementation of the above method 'notifyObservers' was inherited from the trait,
    // and please note that the Java implementation could not do that,
    // but had to delegate the invocation to an instance variable that
    // was duplicated in both Java implementations
  }
}


/**
 * This class does not need to duplicate the code in ObservableTrait, i.e. the implementation
 * code can be inherited even though the class has another base class.
 */
class ProductImplementedInScala
  extends ProductBaseClassWithImplementationIrrelevantForTheExample // Java base class
  with Product // Java interface defining the methods 'setPrice' and 'addObserver'
  with ObservableTrait // provides e.g. the implementation of the method 'addObserver'
{
  private var price: java.lang.Double = null
  def setPrice(price: java.lang.Double): Unit = {
    this.price = price
    notifyObservers("(Scala implementation) Product price changed. New price: " + price)

    // the implementation of the above method 'notifyObservers' was inherited from the trait,
    // and please note that the Java implementation could not do that,
    // but had to delegate the invocation to an instance variable that
    // was duplicated in both Java implementations    
  }
}

Finally, below is some JUnit test code (and also an extra Observer implementation which will print some output to the console) which will verify the same behaviour for both implementations of the Product and Person interfaces, i.e. each of those observables will be tested twice, once for the Java implementation and once for the Scala implementation.


import java.util.Observable;
import java.util.Observer;
/**
 * This class is not used for the actual "testing" i.e. verification,
 * but it just used as an extra Observer, except from the "mocked" Observer (which actually is not a Mock but rather a Test Spy)
 * which will be verified in the test.
 * Further down you will see the output created when executing the test class. 
 */
public class ConsoleView implements Observer {
    public void update(Observable observable, Object arg) {
        System.out.println("ConsoleView Observer recieved update:" + arg);
    }
}


import org.junit.Test;
import org.mockito.Matchers;
import java.util.Observable;
import java.util.Observer;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.contains;
public class VerifyObservableNotificationsWithJavaAndScala {

    // This observerOutputtingToTheConsole is just used for outputting
    // some stuff to the console, while a Test Spy implementation
    // (created by Mockito) will be used for verifying the notifications
    // that should become sent to the Observers,
    // when the person name and the product price changes
    private final static Observer observerOutputtingToTheConsole = new ConsoleView();

    @Test
    public void verifyObservableNotifications() {
        verifyObservableNotificationForPersonWhenNameChanges(new PersonImplementedInJava());
        verifyObservableNotificationForPersonWhenNameChanges(new PersonImplementedInScala());

        verifyObservableNotificationForProductWhenPriceChanges(new ProductImplementedInJava());
        verifyObservableNotificationForProductWhenPriceChanges(new ProductImplementedInScala());
    }

    private void verifyObservableNotificationForPersonWhenNameChanges(final Person person) {
        final Observer observer = mock(Observer.class);

        person.addObserver(observerOutputtingToTheConsole);
        person.addObserver(observer);

        person.setName("Tomas");

         verify(
             observer,
             times(1)
         ).update(Matchers.anyObject(), contains("Tomas"));
    }    

    private void verifyObservableNotificationForProductWhenPriceChanges(final Product product) {
        final Observer observer = mock(Observer.class);

        product.addObserver(observerOutputtingToTheConsole);
        product.addObserver(observer);
        
        product.setPrice(123.45);

         verify(
             observer,
             times(1)
         ).update(Matchers.anyObject(), contains("123.45"));
    }

}

Except from the above code verifying some Observer notifications, it also produces the following output, since the 'ConsoleView' class was also added as Observer:

ConsoleView Observer recieved update:(Java implementation) Person name changed. New name: Tomas
ConsoleView Observer recieved update:(Scala implementation) Person name changed. New name: Tomas
ConsoleView Observer recieved update:(Java implementation) Product price changed. New price: 123.45
ConsoleView Observer recieved update:(Scala implementation) Product price changed. New price: 123.45
/ Tomas Johansson, Stockholm, Sweden, 2010-01-24