Syntax and Annotation
The@override annotation marks a field as a replacement for a member in a superclass. It enforces a compile-time check to ensure the superclass defines the member being overridden.
Polymorphic Dispatch
Unlike languages that use static binding for fields (where the field accessed is determined by the compile-time type of the reference, often resulting in shadowing), Dart uses dynamic dispatch. In Dart, field access is semantically equivalent to a method call. When a field is overridden, the subclass’s implicit accessors replace the superclass’s accessors in the object’s vtable. Consequently, accessing the field on an instance of the subclass always invokes the subclass’s implementation, even if the instance is statically typed as the superclass.Overriding Configurations
Dart treats fields and property accessors (getters/setters) interchangeably within the interface, allowing three specific overriding configurations.1. Field Overridden by Field
A subclass declares a variable with the same name as the superclass.- Storage: Both the superclass and the subclass allocate independent storage slots for the field. The superclass initializer runs during instantiation, assigning a value to the superclass’s slot.
- Access: The subclass generates new implicit accessors that read from and write to the subclass’s storage slot. The superclass’s storage slot is hidden from the subclass’s public interface but remains accessible within the subclass implementation via the
superkeyword.
2. Field Overridden by Accessors
A subclass replaces a stored variable with explicit computed properties.- Storage: The superclass still allocates memory for its field and executes its initializers.
- Access: The subclass intercepts all read and write operations via its explicit methods. The superclass storage remains allocated but is bypassed by the subclass interface unless explicitly accessed via
super.
3. Accessors Overridden by Field
A subclass replaces abstract or concrete getters/setters with a stored variable.- Storage: The subclass allocates a storage slot.
- Access: The compiler generates implicit accessors for the new field, satisfying the interface contract defined by the superclass’s methods.
Mutability Constraints
The mutability of the overriding field is constrained by the contract established in the superclass.- Final to Non-final (Expansion): A
finalfield (read-only) in the superclass can be overridden by a non-final field (read-write) in the subclass. The subclass satisfies the “read” contract of the superclass and expands the interface by adding a setter. - Non-final to Final (Contraction): A non-final field (read-write) in the superclass cannot be overridden by a
finalfield. The superclass contract requires a setter, which afinalfield fails to provide.
Type Constraints and Covariance
Dart enforces strict type safety rules based on the generated accessors:- Getters: The return type of the overriding getter must be a subtype of (or the same as) the overridden getter.
- Setters: The parameter type of the overriding setter must be a supertype of (or the same as) the overridden setter (contravariance).
The covariant Keyword
To override a field with a narrower subtype (e.g., overriding num with int), the covariant keyword is required. This disables the static check on the implicit setter’s parameter type, allowing the subclass to accept only the specific subtype.
Master Dart with Deep Grasping Methodology!Learn More





