Skip to content

prefer_overriding_parent_equality

v0.4.0 Warning Fix Collection & Type

When a parent class overrides == and hashCode, child classes that add new fields should also override both operators. Otherwise, the inherited equality ignores the child’s fields, meaning two child instances with different field values may be considered equal.

Inheriting a parent’s == without overriding it in the child means the child’s own fields are excluded from equality checks. This causes silent bugs in collections, state comparison, and testing where logically different objects appear identical.

See also: Dart operator == and hashCode | Dart lint: hash_and_equals

class Parent {
final int id;
Parent(this.id);
@override
int get hashCode => id.hashCode;
@override
bool operator ==(Object other) => other is Parent && id == other.id;
}
// Missing both == and hashCode overrides
class Child extends Parent {
final String name;
Child(this.name, int id) : super(id);
}
// Missing hashCode override
class ChildMissingHashCode extends Parent {
final String name;
ChildMissingHashCode(this.name, int id) : super(id);
@override
bool operator ==(Object other) =>
other is ChildMissingHashCode && name == other.name && id == other.id;
}
// Missing == override
class ChildMissingEquals extends Parent {
final String name;
ChildMissingEquals(this.name, int id) : super(id);
@override
int get hashCode => Object.hash(id, name);
}
// Child overrides both == and hashCode
class GoodChild extends Parent {
final String name;
GoodChild(this.name, int id) : super(id);
@override
int get hashCode => Object.hash(id, name);
@override
bool operator ==(Object other) =>
other is GoodChild && id == other.id && name == other.name;
}
// Abstract class is not flagged
abstract class AbstractChild extends Parent {
final String label;
AbstractChild(this.label, int id) : super(id);
}
// Parent does not override equality — no warning
class SimpleParent {
final int x;
SimpleParent(this.x);
}
class SimpleChild extends SimpleParent {
final int y;
SimpleChild(this.y, int x) : super(x);
}

This rule is in the opinionated preset, so it is on with preset: opinionated, or by name:

many_lints.yaml
rules:
prefer_overriding_parent_equality: true

To turn it off again:

many_lints.yaml
rules:
prefer_overriding_parent_equality: false

To keep the rule on but skip certain paths, use per-rule exclude.