How to inherit class properties

I have a CFC that extends another CFC, and I want to inherit properties from super CFC. I use the extends attribute, but my subclass does not inherit properties, however it inherits methods. Both CFCs have accessors="true" . I tried using accessors="false" in a subclass, but this does not work. I mean, when running sets on the test page and dump variables.subclass.getResponse (), it returns {} instead of a JSON string with properties and their values ​​(expected answer below). I really don't want to duplicate property declarations in my subclass. I tested both ColdFusion 9 and Railo 4.2.1.

Actual output:

 {} 

Expected Result:

 {"success":false,"errorCode":"1","successMessage":"","errorDetail":"","statusCode":"200","errors":[],"data":"","requestDurationInMilliseconds":"0","errorMessage":"","statusText":"OK"} 

Sample code below:

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> 

test page

 <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> 
+6
source share
1 answer

From the documentation :

Inheritance of components allows you to import methods and properties of components from one component to another. Inherited components share any methods or properties of the components that they inherit from other components, and ColdFusion initializes the instance data in the parent CFC when creating the CFC instance that extends it.

Given this, I did not understand why the subclass will not contain the properties of the parent component; It seems to me an intuitive opponent. I, like you, expected serialization to include all parent properties and child properties. So I played with your example.

The properties of the parent component seem to act as private Java properties and are not affected by the child component, only accessors. Because automatically created accessors store the value in the variable object area in CFML, the child has full access to the values ​​stored by the parent accessories.

A problem in the source code has arisen how the serializeJSON() function works. The serializeJSON function, apparently, only serializes the properties of the passed component. Your subclass has no properties representing the values ​​set by the parent accessories, so serializeJSON returns {} .

When playing with your class structure, the workaround that I used for your getResponse () method was to create a custom method to display the properties of the components along with the properties of its parents as a structure. I am serializing a structure return from this method instead of the object itself (as Sean suggested in the comments). In the child component, I redefined the method of adding custom properties of the child component to the properties of the parents. I'm not sure how much this complicated method will scale with more complex data structures.

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> 
0
source

Source: https://habr.com/ru/post/973741/


All Articles