Flutter's widget hierarchy and most APIs depend on extends and implements, and Dart treats them differently from Java.
class Dog extends Animal inherits Animal's fields and methods. Override members with the @override annotation and call the parent with super.method(). Constructors aren't inherited; a subclass constructor forwards with super(...), or more concisely with super parameters: Dog(super.name);.
An abstract class can't be instantiated and can declare methods without bodies, which concrete subclasses must implement:
abstract class Shape {
double get area; // abstract getter
String describe() => 'Shape with area $area';
}Dart has no separate interface keyword in the Java sense: every class implicitly defines an interface consisting of its public members. class MockClient implements HttpClient must provide all of them itself — nothing is inherited. A class can extends only one class but implements many.
Use extends to reuse implementation and implements to promise a contract (common for test doubles). Since Dart 3, class modifiers such as interface, base and final let library authors restrict which of these is allowed outside their library.
Object is the root of all non-nullable types. toString, ==, hashCode and noSuchMethod come from it.
Type tests with is promote: if (shape is Circle) print(shape.radius);. Covariance of overridden parameters requires the covariant keyword.
Example
abstract class Shape {
const Shape();
double get area;
String describe() => '$runtimeType with area ${area.toStringAsFixed(1)}';
}
class Rect extends Shape {
final double w, h;
const Rect(this.w, this.h);
@override
double get area => w * h;
}
class Square extends Rect {
const Square(double side) : super(side, side);
@override
String describe() => 'Square! ${super.describe()}';
}
class FakeShape implements Shape { // contract only, nothing inherited
@override double get area => 1;
@override String describe() => 'fake';
}
void main() {
final shapes = <Shape>[Rect(2, 3), Square(2), FakeShape()];
for (final s in shapes) print(s.describe());
// Rect with area 6.0 / Square! Square with area 4.0 / fake
}Remember
extendsinherits code from one superclass- Every class is an implicit interface;
implementscopies only the contract - Abstract classes declare members subclasses must provide
Watch out for
- Using
implementsand expecting to inherit method bodies.