Extend a class
Use the extends keyword to create a subclass derived from a superclass.
Use the super keyword to access members (methods, constructors, etc.) defined in the superclass from within a subclass.
class Television {
void turnOn() {
...
// Code executed inside the superclass method
}
}
// SmartTelevision is the subclass, Television is the superclass
class SmartTelevision extends Television {
@override
void turnOn() {
super.turnOn(); // Call the turnOn method from superclass
// Unique logic for the subclass
...
}
}Code language: Dart (dart)
For example, a regular television acts as the superclass, while a smart television serves as the subclass; the smart television inherits features from the basic television.
extends has another common use case: related to parameterized types covered in the generics chapter.
Practical Example
class Television {
void turnOn() {
print("Power on TV, output basic display signal");
}
}
// SmartTelevision is the subclass, Television is the superclass
class SmartTelevision extends Television {
@override
void turnOn() {
super.turnOn(); // Call the turnOn method from superclass
// Unique logic for the subclass
print("Smart TV: Activate network module, load smart system home screen");
}
}
void main() {
// Instance of regular television
Television normalTv = Television();
print("===== Normal TV Power On =====");
normalTv.turnOn();
// Instance of smart television
SmartTelevision smartTv = SmartTelevision();
print("\n===== Smart TV Power On =====");
smartTv.turnOn();
}Code language: Dart (dart)
Execution Output
D:\dartdemo\firstdart>dart run
Building package executable... (1.4s)
Built firstdart:firstdart.
===== Normal TV Power On =====
Power on TV, output basic display signal
===== Smart TV Power On =====
Power on TV, output basic display signal
Overriding members
1. Overridable Elements
A subclass can override: instance methods (including operators), getters and setters.
2. The @override Annotation
Purpose: Explicitly mark that the method intentionally overrides a superclass member, enabling compiler validation checks.
class Television {
set contrast(int value) {}
}
class SmartTelevision extends Television {
@override // Informs compiler this method overrides superclass implementation
set contrast(num value) {}
}
Code language: JavaScript (javascript)
3. Rules for Valid Overrides
- Return Type: The override method’s return type must match the superclass method’s return type, or be a subtype of it.
- Parameter Type: The override method’s parameter type must match the superclass parameter type, or be a supertype. (As shown in the example:
int→num. num is a supertype of int, which is valid.) - Positional Parameter Count: If the original method has n positional parameters, the overriding method must also declare exactly n positional parameters.
- Generic Constraints: Generic methods cannot override non-generic methods, and non-generic methods cannot override generic methods.
4. The covariant Keyword (Special Case for Type Narrowing)
Standard rules forbid narrowing parameter types (downcasting can trigger runtime type exceptions);
If developers can guarantee no runtime type errors will occur, mark parameters with covariant to enable parameter type narrowing.
When overriding the equality operator ==, you must also override the hashCode getter inherited from Object.
noSuchMethod ()
1. Purpose
When your code attempts to call a non-existent instance method / instance variable, you may override noSuchMethod() to intercept the call and implement custom handling logic.
If left unoverridden, accessing non-existent members will directly throw a NoSuchMethodError.
class A {
@override
void noSuchMethod(Invocation invocation) {
print('You tried to use a non-existent member: ${invocation.memberName}');
}
}
Code language: JavaScript (javascript)
Invocationobject: Stores all information about the invocation (member name, arguments, etc.)
2. Two Prerequisites to Trigger noSuchMethod for Unimplemented Methods (One Must Be Met)
- The static type of the caller receiver is
dynamic; - The receiver’s static type declares the unimplemented method (it may be an abstract method), and the receiver’s runtime type provides a custom
noSuchMethod()different from the built-in implementation insideObject.
Example
class A {
@override
void noSuchMethod(Invocation invocation) {
print('You tried to use a non-existent member: ${invocation.memberName}');
// Print extra invocation details to demonstrate full call information
print('Arguments passed:${invocation.arguments}');
print('Invocation type:${invocation.runtimeType}');
}
}
void main() {
A obj = A();
// Call undefined method, triggers noSuchMethod
obj.hello("test", 123);
// Access undefined property
obj.unknownValue;
}Code language: Dart (dart)
D:\dartdemo\firstdart>dart run
Building package executable...
Failed to build firstdart:firstdart:
bin/firstdart.dart:6:30: Error: The getter 'arguments' isn't defined for the type 'Invocation'.
- 'Invocation' is from 'dart:core'.
Try correcting the name to the name of an existing getter, or defining a getter or field named 'arguments'.
print('cal:${invocation.arguments}');
^^^^^^^^^
bin/firstdart.dart:14:7: Error: The method 'hello' isn't defined for the type 'A'.
- 'A' is from 'bin/firstdart.dart'.
Try correcting the name to the name of an existing method, or defining a method named 'hello'.
obj.hello("test", 123);
^^^^^
bin/firstdart.dart:16:7: Error: The getter 'unknownValue' isn't defined for the type 'A'.
- 'A' is from 'bin/firstdart.dart'.
Try correcting the name to the name of an existing getter, or defining a getter or field named 'unknownValue'.
obj.unknownValue;Code language: PHP (php)
Class Inheritance and Member Overriding