A nice example is an object-oriented encoding of booleans. Most languages, even object-oriented ones like Java, opt for an Abstract-Data-Type-oriented encoding of booleans, but e.g. Smalltalk uses an OO encoding, and almost none of the methods make use of any instance state. It looks a bit like this:
import java.util.function.Supplier;
@FunctionalInterface interface Block { void call(); }
interface Bool {
Bool not();
Bool and(Bool other);
Bool or(Bool other);
<T> T ifThenElse(Supplier<T> thenBranch, Supplier<T> elseBranch);
void ifThenElse(Block thenBranch, Block elseBranch);
static final Bool T = new TrueClass();
static final Bool F = new FalseClass();
class TrueClass implements Bool {
public Bool not() { return F; }
public Bool and(Bool other) { return other; }
public Bool or(Bool other) { return this; }
public <T> T ifThenElse(Supplier<T> thenBranch, Supplier<T> elseBranch) {
return thenBranch.get();
}
public void ifThenElse(Block thenBranch, Block elseBranch) {
thenBranch.call();
}
}
class FalseClass implements Bool {
public Bool not() { return T; }
public Bool and(Bool other) { return this; }
public Bool or(Bool other) { return other; }
public <T> T ifThenElse(Supplier<T> thenBranch, Supplier<T> elseBranch) {
return elseBranch.get();
}
public void ifThenElse(Block thenBranch, Block elseBranch) {
elseBranch.call();
}
}
}
public class Main {
public static void main(String... args) {
Bool.F.ifThenElse(() -> System.out.println("True"), () -> System.out.println("False"));
// False
}
}
In fact, if you follow a serious commitment to OO, use a lot of referentially transparent methods, and favor polymorphism over conditionals, you will often end up with methods in lots of subclasses, where each implementation in one of the classes returns a constant value.
static
method cannot implement methods from inherited interfaces. Astatic
method is not subject to polymorphism.static
methods are in fact very limited as to their capabilities. – Cuenca