LEVIATHAN v962456e · 962456eee1

Declarations

override

Mark a member that must replace an inherited member or satisfy an interface requirement, and the warning for a member that almost does.

since 0.1.0-alpha.1linuxwindowswasm

Description

override is an optional member modifier. When it is written, the compiler checks that the member really replaces something: a member marked override must have the same name and signature as a member the class inherits from a base class, or satisfy a requirement of an interface the class lists. Without the marker the member behaves exactly as before, so the marker never changes what a program does; it only turns a misspelled or mis-typed override into an error.

class Fighter : Job {
    override string act() => "fights";
}

The marker works on methods and on fields. A field that a class restates along a single chain of bases (override int hp = 7;) may carry it, and so may a member that redeclares an inherited distinct member. A struct member that satisfies an interface requirement counts: interface requirements are valid targets for override.

When a member is not marked but its name is one edit away from an inherited member of the same kind, the compiler warns that an override may have been intended. The warning is on by default and does not stop the program.

Rules

  • A member marked override that matches no inherited member and no interface requirement is a compile error. When no inherited member has that name:

    error: 'atc' is marked `override` but no base of 'Fightr' declares 'atc() -> string'
    

    If an inherited member is a near miss, a note names it ('Job' declares 'act() -> string').

  • When an inherited member has the name but a different signature, the signature is reported, with a note for each inherited member of that name:

    error: 'act' is marked `override` but its signature '(int) -> string' matches no inherited 'act'
    
  • override applies to fields and methods only. On a constructor or an accessor it is an error:

    error: `override` applies to fields and methods, not constructors or accessors
    
  • An unmarked member that almost matches an inherited member produces a warning. A member almost matches when the name is one edit away (a letter inserted, removed or changed, or two neighbouring letters swapped) or differs only in letter case, the member has the same kind as the inherited one (a method with the same number of parameters, or a field of the same type), and both names are three or more characters long. Names that differ only in trailing digits, such as put and put2, are treated as a family and do not warn:

    warning: 'atc' does not override anything; 'Job' declares 'act() -> string' — rename it to 'act' if an override was intended
    
  • The warning is for classes that list a base. Standard-library classes never produce it.

  • Marking a member override that redeclares an inherited distinct member is accepted.

Examples

Markers that are accepted

interface IShape { int area(); }
struct Square : IShape {
    int side = 3;
    override int area() => side * side;
}
class Job { string act() => "work"; }
class Fighter : Job { override string act() => "fight"; }
class Race { int hp = 2; }
class Elf : Race { override int hp = 7; }
int override = 6;
console.writeln(Square().area());
console.writeln(Fighter().act());
console.writeln(Elf().hp);
console.writeln(override);
9
fight
7
6

The struct member satisfies the interface requirement, the method and the field replace inherited members, and override is an ordinary variable name where no member can follow it.

Notes

override is contextual: it is a modifier only where a member can start after it, so a field, variable or function named override keeps working.

See also

  • Classes — Declare reference types with fields, methods, constructors and accessors, with generics and inheritance from one or more base classes.
  • Interfaces — Declare the members a class must provide, including fields, and let any class satisfy them by declaring those members.
  • Multiple inheritance — Combine several base classes, how same-named fields and methods collapse or stay separate, and how to reach one base's member by qualification.
  • distinct fields — Keep same-named fields of different bases in separate slots, reached by qualification.
  • Keywords — The reserved words, the contextual words that are ordinary identifiers elsewhere, and the keywords that may still name members.