Parent Class References Child Class
ID |
java.parent_class_references_child |
Severity |
high |
Remediation Complexity |
medium |
Remediation Risk |
low |
Remediation Effort |
medium |
Resource |
Code Smell |
Language |
Java |
Tags |
code-style, reliability |
Description
Reports references from a parent class to one of its subclasses within the same compilation unit. This constitutes an inverted dependency that tightly couples the parent to its children.
The superclass is matched on the whole name written in the extends clause, not on its last segment. Matching only the last segment makes a class its own child whenever the superclass merely ends in the same identifier — class Builder extends AbstractResponse.Builder<…> for a nested builder, class Settings extends org.sonar.api.config.Settings for a same-named type in another package — and every self-reference in the class then reads as a parent referencing its child.
Rationale
A well-designed type hierarchy has children depending on parents, never the reverse. When a parent class directly references a subclass — via new ChildClass(), instanceof ChildClass, a field of type ChildClass, or any other reference — the dependency is inverted. This creates:
-
Cyclic coupling — parent and child cannot be compiled, tested, or evolved independently.
-
Fragile base class — adding, renaming, or removing a subclass forces changes in the parent.
-
Violated Open/Closed Principle — extending the hierarchy requires modifying the existing parent class.
// Bad -- parent knows about child
class Shape {
boolean isCircle() {
return this instanceof Circle;
}
}
class Circle extends Shape {}
Remediation
Move child-specific logic into the child class using polymorphism, or use a factory / registry pattern external to the hierarchy.
// Good -- polymorphism instead of instanceof
abstract class Shape {
abstract String kind();
}
class Circle extends Shape {
@Override String kind() { return "circle"; }
}