Instantiation order with extended components
The particular order that a child and parent component are instantiated should be noted. The initialization code, that is, the code in a component that is outside cffunction tags, is executed first in the parent. For example, if you have a parent/base component:
- <!--- employee --->
- <cfcomponent>
- <cfset this.salary = 50000>
- <cfset init()>
- <cffunction name="init" access="public" returntype="employee">
- <cfset this.overtimeSalary = this.salary * otMult()>
- </cffunction>
- <cffunction name="otMult" access="private">
- <cfreturn 1.5>
- </cffunction>
- </cfcomponent>
- <!--- manager --->
- <cfcomponent extends="employee">
- <cfset this.salary = 70000>
- <cffunction name="init" access="public" returntype="manager">
- ...
- </cffunction>
- <cffunction name="otMult" access="private">
- <cfreturn 2>
- </cffunction>
- </cfcomponent>
then instantiating an object of type Manager will have a salary property set to 70000, because the cfset runs in Employee first, and then in Manager.
This makes pretty good sense to me. The values of the child component override the values set in the parent.
This doesn't apply only to variables being set, though (whether it be the public this scope or the private variables scope). If you call a function from the initialization code of a parent component, the function is called as it exists in the parent - the child part of the object has not been instantiated yet.
So with the example components above, the call to init() from within the initialization code of the parent component, Employer, makes a reference to the otMult() function. Since the child part of the object has not been instantiated yet, the otMult() call returns 1.5, instead of the value of 2 you might want if you are instantiating a Manager.
If this becomes a problem for you, I suggest that you NOT try to call your initialization functions from the initialization code block of a component, and instead, put all your initialization code within init functions and call your init() function when you instantiate an object:
- <cfset myManager = CreateObject("component", "Manager").init()>
Happy Coding!