blob: 008f9690b8ce363ba2fa91d947361b6ef1bb42fa [file] [log] [blame]
// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
part of dart.core;
/// The base class for all Dart objects exception `null`.
///
/// Because `Object` is a root of the non-nullable Dart class hierarchy,
/// every other non-`Null` Dart class is a subclass of `Object`.
///
/// When you define a class, you should consider overriding [toString]
/// to return a string describing an instance of that class.
/// You might also need to define [hashCode] and [operator ==], as described in the
/// [Implementing map keys](https://dart.dev/guides/libraries/library-tour#implementing-map-keys)
/// section of the [library tour](https://dart.dev/guides/libraries/library-tour).
@pragma("vm:entry-point")
class Object {
/// Creates a new [Object] instance.
///
/// [Object] instances have no meaningful state, and are only useful
/// through their identity. An [Object] instance is equal to itself
/// only.
@pragma("vm:recognized", "other")
const Object();
/// The equality operator.
///
/// The default behavior for all [Object]s is to return true if and
/// only if this object and [other] are the same object.
///
/// Override this method to specify a different equality relation on
/// a class. The overriding method must still be an equivalence relation.
/// That is, it must be:
///
/// * Total: It must return a boolean for all arguments. It should never throw.
///
/// * Reflexive: For all objects `o`, `o == o` must be true.
///
/// * Symmetric: For all objects `o1` and `o2`, `o1 == o2` and `o2 == o1` must
/// either both be true, or both be false.
///
/// * Transitive: For all objects `o1`, `o2`, and `o3`, if `o1 == o2` and
/// `o2 == o3` are true, then `o1 == o3` must be true.
///
/// The method should also be consistent over time,
/// so whether two objects are equal should only change
/// if at least one of the objects was modified.
///
/// If a subclass overrides the equality operator, it should override
/// the [hashCode] method as well to maintain consistency.
external bool operator ==(Object other);
/// The hash code for this object.
///
/// A hash code is a single integer which represents the state of the object
/// that affects [operator ==] comparisons.
///
/// All objects have hash codes.
/// The default hash code implemented by [Object]
/// represents only the identity of the object,
/// the same way as the default [operator ==] implementation only considers objects
/// equal if they are identical (see [identityHashCode]).
///
/// If [operator ==] is overridden to use the object state instead,
/// the hash code must also be changed to represent that state,
/// otherwise the object cannot be used in hash based data structures
/// like the default [Set] and [Map] implementations.
///
/// Hash codes must be the same for objects that are equal to each other
/// according to [operator ==].
/// The hash code of an object should only change if the object changes
/// in a way that affects equality.
/// There are no further requirements for the hash codes.
/// They need not be consistent between executions of the same program
/// and there are no distribution guarantees.
///
/// Objects that are not equal are allowed to have the same hash code.
/// It is even technically allowed that all instances have the same hash code,
/// but if clashes happen too often,
/// it may reduce the efficiency of hash-based data structures
/// like [HashSet] or [HashMap].
///
/// If a subclass overrides [hashCode], it should override the
/// [operator ==] operator as well to maintain consistency.
external int get hashCode;
/// A string representation of this object.
///
/// Some classes have a default textual representation,
/// often paired with a static `parse` function (like [int.parse]).
/// These classes will provide the textual representation as
/// their string represetion.
///
/// Other classes have no meaningful textual representation
/// that a program will care about.
/// Such classes will typically override `toString` to provide
/// useful information when inspecting the object,
/// mainly for debugging or logging.
external String toString();
/// Invoked when a non-existent method or property is accessed.
///
/// A dynamic member invocation can attempt to call a member which
/// doesn't exist on the receiving object. Example:
/// ```dart
/// dynamic object = 1;
/// object.add(42); // Statically allowed, run-time error
/// ```
/// This invalid code will invoke the `noSuchMethod` memthod
/// of the integer `1` with an [Invocation] representing the
/// `.add(42)` call and arguments (which then throws).
///
/// Classes can override [noSuchMethod] to provide custom behavior
/// for such invalid dynamic invocations.
///
/// A class with a non-default [noSuchMethod] invocation can also
/// omit implementations for members of its interface.
/// Example:
/// ```dart
/// class MockList<T> implements List<T> {
/// noSuchMethod(Invocation invocation) {
/// log(invocation);
/// super.noSuchMethod(invocation); // Will throw.
/// }
/// }
/// void main() {
/// MockList().add(42);
/// }
/// ```
/// This code has no compile-time warnings or errors even though
/// the `MockList` class has no concrete implementation of
/// any of the `List` interface methods.
/// Calls to `List` methods are forwarded to `noSuchMethod`,
/// so this code will `log` an invocation similar to
/// `Invocation.method(#add, [42])` and then throw.
///
/// If a value is returned from `noSuchMethod`,
/// it becomes the result of the original invocation.
/// If the value is not of a type that can be returned by the original
/// invocation, a type error occurs at the invocation.
///
/// The default behavior is to throw a [NoSuchMethodError].
@pragma("vm:entry-point")
external dynamic noSuchMethod(Invocation invocation);
/// A representation of the runtime type of the object.
external Type get runtimeType;
}