wel*_*rcs 6 coldfusion inheritance
我有一个CFC正在扩展另一个CFC,我想继承超级CFC的属性.我使用extends属性,但我的子类不继承属性,但它继承了方法.两种氟氯化碳都有accessors="true"
.我尝试accessors="false"
在子类中使用,但这不起作用.我的意思是当我在测试页面中运行集合并转储variables.subclass.getResponse()时,它返回{}而不是带有属性及其值的JSON字符串(下面的预期响应).我真的不想在我的子类中复制属性声明.我在ColdFusion 9和Railo 4.2.1上进行了测试.
实际产量:
{}
Run Code Online (Sandbox Code Playgroud)
预期产量:
{"success":false,"errorCode":"1","successMessage":"","errorDetail":"","statusCode":"200","errors":[],"data":"","requestDurationInMilliseconds":"0","errorMessage":"","statusText":"OK"}
Run Code Online (Sandbox Code Playgroud)
示例代码如下:
superclass.cfc
<cfscript>
component accessors="true" {
property name="data" type="any" required="false" getter="true";
property name="errorCode" type="numeric" required="false" getter="true";
property name="errorDetail" type="any" required="false" getter="true";
property name="errorMessage" type="string" required="false" getter="true";
property name="errors" type="array" required="false" getter="true";
property name="requestDurationInMilliseconds" type="numeric" required="false" getter="true";
property name="statusCode" type="numeric" required="false" getter="true";
property name="statusText" type="string" required="false" getter="true";
property name="success" type="boolean" required="false" getter="true";
property name="successMessage" type="string" required="false" getter="true";
this.setData("");
this.setErrorCode(0);
this.setErrorDetail("");
this.setErrorMessage("");
this.setErrors([]);
this.setRequestDurationInMilliseconds(0);
this.setStatusCode(200);
this.setStatusText("OK");
this.setSuccess(true);
this.setSuccessMessage("");
public superclass function init() {
return this;
}
public function getResponse( string format="json" ) {
if ( structKeyExists(arguments,"format") and arguments.format is "json" ) {
return serializeJSON(this);
}
else {
return this;
}
}
}
</cfscript>
Run Code Online (Sandbox Code Playgroud)
subclass.cfc
<cfscript>
component accessors="true" extends="superclass" {
// property name="data" type="any" required="false" getter="true";
// property name="errorCode" type="numeric" required="false" getter="true";
// property name="errorDetail" type="any" required="false" getter="true";
// property name="errorMessage" type="string" required="false" getter="true";
// property name="errors" type="array" required="false" getter="true";
// property name="requestDurationInMilliseconds" type="numeric" required="false" getter="true";
// property name="statusCode" type="numeric" required="false" getter="true";
// property name="statusText" type="string" required="false" getter="true";
// property name="success" type="boolean" required="false" getter="true";
// property name="successMessage" type="string" required="false" getter="true";
}
</cfscript>
Run Code Online (Sandbox Code Playgroud)
测试页面
<cfscript>
variables.subclass = new subclass();
variables.subclass.setSuccess(false);
variables.subclass.setErrorCode(1);
writedump(getMetaData(variables.subclass));
writedump(variables.subclass);
writedump(variables.subclass.getResponse());
</cfscript>
Run Code Online (Sandbox Code Playgroud)
从文档中:
组件继承允许您将组件方法和属性从一个组件导入到另一组件。继承的组件共享它们从其他组件继承的任何组件方法或属性,并且当您实例化扩展父 CFC 时,ColdFusion 会初始化父 CFC 中的实例数据。
鉴于此,我不明白为什么子类不包含父组件的属性;这对我来说似乎违反直觉。我和您一样,期望序列化包含所有父属性和子属性。所以我用你的例子来玩。
父组件的属性看起来就像Java私有属性,并且不暴露给子组件,只有访问器。由于自动生成的访问器将值存储到 CFML 中的对象变量范围中,因此子访问器可以完全访问父访问器存储的值。
原始代码中的问题源于该serializeJSON()
函数的工作原理。SerializeJSON 函数似乎只序列化传递组件的属性。您的子类没有表示父访问器设置的值的属性,因此 serializeJSON 返回{}
。
在使用您的类结构时,我为 getResponse() 方法想出的解决方法是创建一个自定义方法,以将组件属性及其父级属性公开为结构。我序列化从此方法返回的结构,而不是对象本身(如 Sean 在评论中所建议的那样)。在子组件中,我重写了将子组件的自定义属性附加到父组件属性上的方法。我不确定这个重写方法对于更复杂的数据结构的扩展效果如何。
超类.cfc
component accessors="true" {
property name="data" type="any";
public superclass function init() {
data = "Super Class Value";
return this;
}
public function getResponse( string format="json" ) {
if ( structKeyExists(arguments,"format") and arguments.format is "json" ) {
return serializeJSON(getProperties());
}
else {
return getProperties();
}
}
public struct function getProperties(){
return {
"data" = data
};
}
}
Run Code Online (Sandbox Code Playgroud)
子类.cfc
component accessors="true" extends="superclass" {
property name="subData" type="any";
public subClass function init() {
// Could use super.init() to pull parent defaults
data = "Sub Class Value";
Subdata = "Sub property";
return this;
}
public struct function getProperties(){
local.properties = super.getProperties();
structappend(local.properties,{
"subData" = subData
});
return local.properties;
}
}
Run Code Online (Sandbox Code Playgroud)
测试.cfm
<cfoutput>
<cfset superclass = new superclass()>
<cfset subclass = new subclass()>
super class
<br />
#serializejson(superclass)# // Has one properties to serialize on
<br />
GetResponse with custom function:
<br />
#superclass.getResponse()# // Displays one property
<br /><br />
sub class
<br />
#serializejson(subclass)# // One property to serialize
<br />
GetResponse with custom function:
<br />
#subclass.getResponse()# // Two properties serialized
</cfoutput>
Run Code Online (Sandbox Code Playgroud)