An interface is a contract: a list of method signatures with no implementation at all. Any component that implements it promises to provide real versions of every one of those methods, or ColdFusion raises an error.
Where extends builds a direct "is-a" relationship to one parent, implements is about a component promising it can do certain things — and a component can implement several interfaces at once, which is how ColdFusion gets the benefit of multiple inheritance without actually allowing it.
Learning Objectives
After completing this lesson, you'll be able to:
- Define an interface with interface / <cfinterface>.
- Implement one interface — and more than one at once — on a component.
- Explain how implementing multiple interfaces differs from multiple inheritance.
Defining an Interface
interface {
numeric function calculateTotal();
}<cfinterface>
<cffunction name="calculateTotal" returnType="numeric">
</cffunction>
</cfinterface>Implementing an Interface
component implements="Payable" {
property name="items" type="array";
function init(required array items) {
variables.items = arguments.items;
return this;
}
numeric function calculateTotal() {
var total = 0;
for (var item in variables.items) {
total += item.price;
}
return total;
}
}<cfcomponent implements="Payable">
<cfproperty name="items" type="array">
<cffunction name="init">
<cfargument name="items" type="array" required="true">
<cfset variables.items = arguments.items>
<cfreturn this>
</cffunction>
<cffunction name="calculateTotal" returnType="numeric">
<cfset var total = 0>
<cfloop array="#variables.items#" index="item">
<cfset total += item.price>
</cfloop>
<cfreturn total>
</cffunction>
</cfcomponent>If calculateTotal() were left out of Invoice.cfc, ColdFusion would raise an error — implements is a promise the component is required to keep.
Implementing More Than One Interface
This is the substitute for multiple inheritance: a component can only extend one parent, but it can implement as many interfaces as it needs, comma-delimited.
component implements="Payable,Printable" {
// must implement every method from both Payable and Printable
}<cfcomponent implements="Payable,Printable">
<!--- must implement every method from both Payable and Printable --->
</cfcomponent>Common Beginner Mistakes
Adding a body to a method inside an interface
An interface only declares signatures — name, arguments, return type — with no implementation. (ColdFusion 2021+ does allow default interface methods with a real body, but that's an exception, not the norm.)
Forgetting to implement every method the interface requires
A component that implements an interface but leaves one of its methods unimplemented raises an error — the interface is a full contract, not a suggestion.
Best Practices
- Use extends for a genuine "is-a" relationship with shared implementation, and implements for "can-do" capabilities that might apply across otherwise unrelated components.
- Keep interfaces small and focused on one capability — a component implementing several small interfaces is usually more flexible than one implementing a single large one.
Interview Questions
What's required of a component that implements an interface?
It must provide a real implementation of every method declared in that interface, matching the required signatures, or ColdFusion raises an error.
How does implementing multiple interfaces get around ColdFusion's lack of multiple inheritance?
A CFC can only extend one parent, but it can implement as many interfaces as needed at once — giving it multiple behavioral contracts without needing multiple parent classes.
Summary
In this lesson, you defined an interface, implemented it on a component, and covered how implementing multiple interfaces substitutes for the multiple inheritance ColdFusion doesn't allow.
What's Next?
The final lesson in this module covers method overriding in more depth — the rules for a valid override, and the final keyword that prevents one.