如何继承类属性

时间:2014-08-13 01:52:15

标签: inheritance coldfusion

我有一个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>

1 个答案:

答案 0 :(得分:0)

来自documentation

  

组件继承允许您将组件方法和属性从一个组件导入另一个组件。继承的组件共享它们从其他组件继承的任何组件方法或属性,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>