我有一个CFC正在扩展另一个CFC,我想继承超级CFC的属性。我使用extends属性,但我的子类不继承属性,但它继承了方法。两个CFC都有accessors="true"
。我尝试在子类中使用accessors="false"
,但这不起作用。我的意思是当我在测试页面中运行集合并转储variables.subclass.getResponse()时,它返回{}而不是带有属性及其值的JSON字符串(下面的预期响应)。我真的不想在我的子类中复制属性声明。我在ColdFusion 9和Railo 4.2.1上进行了测试。
实际输出:
{}
预期产出:
{"success":false,"errorCode":"1","successMessage":"","errorDetail":"","statusCode":"200","errors":[],"data":"","requestDurationInMilliseconds":"0","errorMessage":"","statusText":"OK"}
以下示例代码:
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>
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>
测试页
<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>
答案 0 :(得分:0)
组件继承允许您将组件方法和属性从一个组件导入另一个组件。继承的组件共享它们从其他组件继承的任何组件方法或属性,ColdFusion在实例化扩展它的CFC时初始化父CFC中的实例数据。
鉴于此,我不明白为什么子类不包含父组件的属性;这似乎与我相反。我和您一样,希望序列化包含所有父属性和子属性。所以我玩了你的例子。
父组件的属性似乎像Java私有属性一样,并且不向子组件公开,只有访问器公开。由于自动生成的访问器将值存储到CFML中的对象变量范围中,因此子进程可以完全访问父访问器存储的值。
原始代码中的问题源自serializeJSON()
函数的工作原理。 serializeJSON函数似乎只序列化传递的组件的属性。您的子类没有表示父控制器设置的值的属性,因此serializeJSON返回{}
。
在使用类结构时,我为getResponse()方法提出的解决方法是创建一个自定义方法,以将组件属性及其父属性公开为结构。我从这个方法而不是对象本身序列化struct return(正如Sean在评论中所建议的那样)。在子组件中,我重写了将子组件的自定义属性附加到父属性的方法。我不确定这种覆盖方法将如何与更复杂的数据结构进行扩展。
<强> SuperClass.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
};
}
}
<强> SubClass.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;
}
}
<强> Test.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>