"""The abstract supertype of all types representing definite values. Any two values which are assignable to `Object` may be compared for value equality using the `==` and `!=` operators, even if the values are of different concrete type: true == false 1 == "hello world" "hello"+" "+"world" == "hello world" Singleton("hello world") == ["hello world"] However, since [[Null]] is not a subtype of `Object`, the value [[null]] cannot be compared to any other value using the `==` operator. Thus, value equality is not defined for optional types. This neatly bypasses the problem of deciding the value of the expression `null==null`, which is simply illegal. A concrete subclass of `Object` must refine [[equals]] and [[hash]] (or inherit concrete refinements), providing a concrete definition of value equality for the class.""" see (`class Basic`, `class Null`) by ("Gavin") shared abstract class Object() extends Anything() { "Determine if two values are equal. Implementations should respect the constraints that: - if `x===y` then `x==y` (reflexivity), - if `x==y` then `y==x` (symmetry), - if `x==y` and `y==z` then `x==z` (transitivity). Furthermore it is recommended that implementations ensure that if `x==y` then `x` and `y` have the same concrete class. A class which explicitly refines `equals()` is said to support _value equality_, and the equality operator `==` is considered much more meaningful for such classes than for a class which simply inherits the default implementation of _identity equality_ from [[Identifiable]]." shared formal Boolean equals(Object that); "The hash value of the value, which allows the value to be an element of a hash-based set or key of a hash-based map. Implementations must respect the constraint that: - if `x==y` then `x.hash==y.hash`. Therefore, a class which refines [[equals]] must also refine `hash`." shared formal Integer hash; "A developer-friendly string representing the instance. Concatenates the name of the concrete class of the instance with the `hash` of the instance. Subclasses are encouraged to refine this implementation to produce a more meaningful representation." shared default String string => className(this) + "@" + hash.string; }