Rich.thibault wrote:
public interface IMediaExporter {
public IMediaExporter getInstance();
}
public class MediaExporter implements IMediaExporter {
public MediaExporter getInstance() {
return this;
}
}
This does not work in CF:
<cfinterface>
<cffunction name="getInstance" output="false"
returntype="IMediaExporter">
</cffunction>
</cfinterface>
<cfcomponent output="false"
implements="IMediaExporter">*
<cffunction name="getInstance" output="false"
returntype="MediaExporter">*
<cfscript>
return this;
</cfscript>
</cffunction>
</cfcomponent>
-==cfSearching==- wrote:
Since CF does not support overloading either, I would not be
very surprised if it did not support covariant return types, by
design. Personal preferences aside, it does mention in the
documentation "Must be identical to value in interface; however, an
omitted type option and an option value of any are equivalent".
That certainly does read as if it was a conscious decision. Though
the fact that you can also return "any" muddies the waters a
bit.
I suspect it's got to do with the fact that Java's concept of
static type-checking doesn't (yet) carry over to Coldfusion. I am
referring to the meaning static that is opposed to dynamic or
runtime.
The static type is the type of the reference. Java checks the
static type at compile-time. To borrow from your example, one may
write in Java
IMediaExporter myMediaExporter = new MediaExporter();
Here, the static type, that is, the type of the reference, is
the interface, IMediaExporter. There is no equivalent to that line
of code in Coldfusion components. Coldfusion has (as yet) no
static-type checking. I guess that that is the reason behind the
requirement that the return types be identical or else "any".
However, all is not lost. Modify your code as follows.
<cfinterface>
<cffunction name="getInstance" output="false"
returntype="IMediaExporter">*
</cffunction>
</cfinterface>
<cfcomponent output="false"
implements="IMediaExporter">
<cffunction name="getInstance" output="false"
returntype="IMediaExporter">*
<cfscript>
return this;
</cfscript>
</cffunction>
</cfcomponent>
<!--- IMediaExporter type --->
<cfset iObj = createobject("component",
"MediaExporter").getInstance()>
<p>Is returned IMediaExporter type an instance of
MediaExporter:
<cfoutput>#isInstanceOf(iObj,'MediaExporter')#</cfoutput></p>
Coldfusion would tell you that the returned IMediaExporter
type is an instance of MediaExporter. Also, there is always the
possibility to leave everything unchanged in your Java code, and to
do this:
<cfset obj=createobject("java","MediaExporter")>
<cfset iObj=createobject("java","IMediaExporter")>
*
Correction following feedback from Rich-thibault and
-==cfSearching==-. The type returned should indeed be the interface
IMediaExporter , not the component MediaExporter. There is no such
thing as an instantiation of the interface, as I, myself, pointed
out. (NB: I interprete Coldfusion's isInstanceOf to mean, in the
case of interfaces, typing rather than instantiation)