Quick design question: why go from interfaces to abstract classes (for Try and Option, for example)?
Interfaces can be implemented by everyone, therefore it is a security hole. Option, Try etc only have two implementations (Some/None, Success/Failure etc). Because Java does not have sealed interfaces, we can only use an abstract class to hide the constructor. Alternatively we could have used a final class without inheritance (like Java鈥榮 Optional).
Allowing only specific implementations is essential when it comes to pattern matching. Otherwise the compiler could not guarantee exhaustive checks. (Look at Scala)
// a future Java switch expression
var res = switch myOption {
case Some(t) -> doSomeThingWith(t)
case None -> doSthElse()
// no other case possible if Option is sealed!
}
// can't guarantee that there are
interface Option<T> {
static class Some<T> implements Option<T> {}
static class None<T> implements Option<T> {}
}
// only two impls possible!
abstract class Option<T> {
private Option() {} // sealed!
static class Some<T> extends Option<T> {}
static class None<T> extends Option<T> {}