The Polymorphism lesson used overriding to give different shapes their own area() logic. This lesson covers overriding as its own topic — the actual rules ColdFusion enforces on a valid override, and the final keyword for the opposite case: locking a method, component, or variable so it can't be changed at all.
Learning Objectives
After completing this lesson, you'll be able to:
- State the rule an overriding method has to follow for its return type.
- Use covariant return types (ColdFusion 2021+) where a subclass narrows a return type.
- Use final to prevent a method from being overridden, a component from being extended, or a variable from being reassigned.
The Basic Rule: Matching Signatures
An overriding method has to accept the same arguments as the parent's version — you can't silently change what a caller is expected to pass. The return type has more flexibility, covered next.
Covariant Return Types (ColdFusion 2021+)
A subclass's override is allowed to narrow the return type to something more specific than the parent declared, as long as the more specific type is still compatible with the parent's.
component {
Animal function adopt() {
return new Animal();
}
}component extends="AnimalShelter" {
Dog function adopt() { // narrowed from Animal to Dog — valid covariant override
return new Dog();
}
}<cfcomponent>
<cffunction name="adopt" returnType="Animal">
<cfreturn new Animal()>
</cffunction>
</cfcomponent><cfcomponent extends="AnimalShelter">
<!--- narrowed from Animal to Dog — valid covariant override --->
<cffunction name="adopt" returnType="Dog">
<cfreturn new Dog()>
</cffunction>
</cfcomponent>This only works because Dog extends Animal — the override's return type still has to be compatible with what the parent promised.
final — Preventing Changes
final does the opposite of an override: it locks something down so it can't be changed further down the line. It applies to methods, whole components, and variables, each with a slightly different effect.
| Where final is used | What it prevents |
|---|---|
| A method | A subclass overriding that specific method |
| A component | Any subclass extending it at all |
| A variable | The value being reassigned after it's first set (a constant) |
component {
final public numeric function calculateTax(numeric amount) {
return amount * 0.18; // subclasses cannot override this specific method
}
}
final component LockedSettings {
// no component can extend LockedSettings at all
}final, like abstract, is a CFScript-only keyword with no <cfcomponent>/<cffunction> tag-syntax equivalent — that's why there's no Tag Syntax version of this example. ColdFusion 2025 added support for combining static and final on a single method — a locked-down, class-level method that can't be overridden and doesn't need an instance to call.
Common Beginner Mistakes
Trying to override a method marked final
It raises an error at compile/load time — final on a method is a hard rule, not a suggestion, specifically to guarantee that method's behavior can never be changed by a subclass.
Widening an overriding method's return type instead of narrowing it
Covariant return types only allow narrowing (a more specific subtype), not widening to something less specific than the parent declared.
Best Practices
- Use final on a method when its correctness genuinely depends on never being changed by a subclass — a security check, a tax calculation, a fixed algorithm.
- Reach for covariant return types when a subclass's override naturally returns something more specific — it lets callers work with the more specific type directly, without a cast.
Interview Questions
What does marking a method final prevent?
Any subclass from overriding that specific method — attempting to do so raises an error.
What's a covariant return type?
When an overriding method's return type is narrowed to something more specific than the parent's declared return type, as long as it's still compatible — supported in ColdFusion 2021 and later.
Summary
In this lesson, you covered the rules a valid method override has to follow, covariant return types, and the final keyword for locking down a method, component, or variable.
That's the whole Object-Oriented Programming module — components, objects, properties, methods, constructors, access control, and all four OOP pillars.
What's Next?
The next module covers Application Development — Application.cfc, the application lifecycle, and the larger scopes (session, application, request) used to hold state across an entire ColdFusion application.