DEFINE PROPERTY statement
- Last Updated: February 17, 2022
- 14 minute read
- OpenEdge
- Version 13.0
- Documentation
Syntax
This is the syntax for defining a property using the DEFINE PROPERTY statement:
|
Element descriptions for this syntax diagram follow:
- [ PRIVATE | PACKAGE-PRIVATE | PROTECTED | PACKAGE-PROTECTED |PUBLIC ]
- The access mode for the property. The
default property access mode is
PUBLIC.PRIVATEproperties are accessible from within the class where they are defined. An instance can access aPRIVATEproperty of another instance if they are both instances of the same class.PROTECTEDproperties are accessible from within the class where they are defined and in any subclass of the defining class. An instance can access aPROTECTEDproperty of a second instance of a class that is at the same level or in a super class in the class hierarchy. APACKAGE-PRIVATEproperty can be accessed from within the class and any class within its package. APACKAGE-PROTECTEDproperty can be accessed from within the class, any class within its package, and from within any subclass that inherits the class.PUBLICproperties are accessible both within the class hierarchy and from outside the class hierarchy where they are defined. For more information on accessing properties, see Access data members and properties. - [ STATIC ]
- Specifies the scope of the property. By default, properties of a class are instance properties, meaning that one copy of a given property is created and scoped to each instance of the class in which it is defined. However, properties can also be defined as static using this keyword. ABL creates only one copy of a static property on first reference to the class type in which it is defined, scopes that property to the class type, and makes it available through that class type for the duration of the ABL session. Unless specified otherwise, any reference to a property in this manual is assumed to be a reference to an instance property.
- [ ABSTRACT ]
- Declares the property as abstract using an abstract property
prototype. Each abstract property prototype is declared by a single
DEFINE PROPERTYstatement, with one or both of the two possible accessors specified, but with no accessor implementations. This means that appropriate access mode and data type information is specified for each accessor, but the accessor code block must be empty. Abstract properties can be defined as eitherPROTECTEDorPUBLIC. These property prototypes cannot specify theINITIALorSTATICoption. An abstract property has no storage allocated for it to hold an initial value and it can only be an instance property. - [ FINAL ]
- Indicates that this property cannot be overridden.
This option is not valid when you define a static or abstract property or when you declare an interface property prototype.
- [ OVERRIDE ]
- Specifies that this instance property
overrides a property inherited from an ABL or .NET property. When you specify
OVERRIDE, the property definition must match the inherited property with respect to name, data type (including array dimensions), specified accessors (GETorSET), andNO-UNDOsetting. In addition, the access mode must not be more restrictive than the access mode defined for the overridden property. When overriding a .NET property, the data type must also map appropriately to the inherited .NET property data type.The overriding property can redefine the property as abstract as long as the defining class is also abstract. Also, if the current class definition is abstract, you do not need to override an inherited abstract property that you want to remain abstract, unless you want to specify a less restrictive access mode, or you want to add an unspecified accessor to the inherited abstract prototype
- [ SERIALIZABLE | NON-SERIALIZABLE ]
- Class-based objects that are defined as serializable (using the
SERIALIZABLEoption in theCLASSstatement) can be passed as parameters in remotes call between the application server and ABL clients and can be serialized to binary or JSON format. By default, both passing an object as a parameter and serializing an object to binary via theProgress.IO.BinarySerializerclass include all data members regardless of access mode. However, for JSON serialization viaProgress.IO.JsonSerializer, only public data members are serialized. To include a protected or private property during JSON serialization,SERIALIZABLEmust be added to the definition. See theSerialize( ) method (JsonSerializer)entry in ABL Reference for more information. - property-name
- The property name, which identifies either the property or its default memory, depending on the context. This property-name must be unique within the class hierarchy according to its particular class member namespace. A property name must be unique within a namespace that includes the names of properties, variable data members, and class events. For more information, see Namespaces for class members.
- type-spec
- The data type of the property and its default memory, specified using
this syntax:
AS {primtive-type-name|[ CLASS ]object-type-name} [ EXTENT [constant ]] - [ INITIAL {constant| [ constant[ , constant] . . . ] }]
- This option specifies an initial value for an implemented property,
depending on the data type. It allows you to define a single value for a scalar property
or all of the element values for an array property, specified as a comma-separated list
within the required square brackets (
[]). - [NO-UNDO]
- Similar to data members, if a transaction is undone in which the property is accessed, this option retains the latest change to the value of property default memory during the transaction.
- accessor-spec
- One or two accessors defined for the property that indicate if the
property is readable, writable, or both.
This syntax specifies two accessors that allow the property to be both readable and writable:
[ PRIVATE | PACKAGE-PRIVATE | PROTECTED | PACKAGE-PROTECTED]get-accessorset-accessor |get-accessor[ PRIVATE | PROTECTED | PACKAGE-PRIVATE | PACKAGE-PROTECTED]set-accessorThe get-accessor represents an accessor that allows the property to be read, and the set-accessor represents an accessor that allows the property to be written. The optional access mode applies only to the immediately following accessor and overrides the specified property access mode. The other accessor always inherits the property access mode. If you specify an access mode for one accessor, it must be more restrictive than the property access mode that applies to the other accessor. However, note that if the property is abstract, the accessor access mode can never be
PRIVATE, because it must be implemented in, and accessible from, an inheriting class.So for example, if the property access mode is
PROTECTEDand you specify aPRIVATEaccess mode on the set-accessor, the get-accessor assumes the access mode of the property, which isPROTECTED. This specifies that the property can only be written from the defining class or an instance of the defining class. The property can be read only from the defining class, an instance of the defining class, a subclass of the defining class, or an instance of a subclass of the defining class.If you want the property to be both read and written using the property access mode (the default), do not specify an accessor access mode.
This syntax specifies a single accessor that allows the property to be read:
get-accessorThis accessor allows the property to be read according to the property access mode. If this is the only accessor that you specify, the property is read-only. You cannot override the property access mode for a read-only property.
This is the syntax for a get-accessor, which specifies how the property is read:
GET. | GET SUPER. | GET ( [array-index-parameter] ) : get-logic END [ GET ].You can define one of three types of accessors for reading the property:
- GET.
- A simple
GETaccessor (defined without an implementation). The property value is read directly from the current value of the default memory for the property. This is the only get-accessor syntax that you can specify for an abstract or interface property prototype. - GET SUPER.
- A
GETaccessor defined with theSUPERoption.SUPERallows you to pass control to the super class. Use theSUPERoption if you want to override one of the accessors to provide extra processing or validation, but don't need to change the implementation of the other accessor. You can also useSUPERto make the access mode of the property less restrictive. - GET ( [array-index-parameter] ) : get-logic END [ GET ].
- A coded
GETaccessor (defined with an implementation). The property value is read from a value returned from get-logic. This get-logic can include any number and types of statements that are valid for a method. These statements can read and write the value of the default memory specified by property-name or the values of any other accessible data elements. If the property is defined as static, get-logic statements can access only other static members defined within the current class hierarchy in addition to its default memory and local accessor data; instance members defined within the current class hierarchy are inaccessible. However, if the property is defined as an instance member, get-logic statements can access static members as well as other instance members.If the property is defined as an array using the
EXTENToption, the get-logic always works on one element of the array at a time, whether the array is read with or without a subscript. If the array is read without a subscript, get-logic executes once for each element in the property array. If specified, the optional array-index-parameter passes the subscript value to the get-logic for the current element being accessed. This is the syntax:[ INPUT ]array-index-name AS { INTEGER | INT64 }The array-index-name provides a name for the index parameter, which can have one of the specified integer data types. Whatever retrieval operation you code for the get-logic can then access the appropriate array element of the property default memory by using array-index-name as the array subscript (property-name
[array-index-name]).To return a value to the property reader, you must use the
RETURNstatement. This statement can return any value compatible with the property’s data type, regardless of the value of property-name. If you do not invoke aRETURNstatement in get-logic, the property returns theUnknown value (?)to the reader.Note: Any statement in get-logic that assigns a value to property-name invokes the propertySETaccessor to assign the value. However, any get-logic statements that read the value of property-name directly read the value most recently assigned to property default memory.If a statement in get-logic raises an
ERRORcondition that is not handled using theNO-ERRORoption, the condition can be handled by the associated block according to itsON ERRORdefinition or the presence of an appropriateCATCHstatement. If the associated block is the accessor, itself, it can also handle the condition according to the defaultON ERRORhandling for method and procedure blocks or according to any specifiedROUTINE-LEVEL ON ERROR UNDO, THROWstatement.A
RETURN ERRORorUNDO, THROWin get-logic that raisesERRORbeyond theGETaccessor block, raises theERRORcondition on the statement that is reading the property. Any data elements (including property default memory) that have been changed by get-logic retain their latest values or revert to their values before this statement executed, depending on their respectiveNO-UNDOsettings. Any optionalRETURN-VALUEsetting or error object can be appropriately accessed after control returns from the statement that is reading the property. For more information on handling errors returned from properties, see Raise and handle error conditions.
This syntax specifies a single accessor that allows the property to be written:
set-accessorThis accessor allows the property to be written according to the specified property access mode. If this is the only accessor that you specify, the property is write-only. You cannot override the property access mode for a write-only property.
This is the syntax for a set-accessor, which specifies how the property is written:
SET. | SET SUPER. | SET ( parameter-definition[ , array-index-parameter] ) : set-logic END [ SET ].You can define one of three types of accessors for writing the property:
- SET.
- A simple
SETaccessor (defined without an implementation). The value written to the property is assigned directly to the default memory for the property. This is the only set-accessor syntax that you can specify for an abstract or interface property prototype. - SET SUPER.
- A
SETaccessor defined with theSUPERoption.SUPERallows you to pass control to the super class. Use theSUPERoption if you want to override one of the accessors to provide extra processing or validation, but don't need to change the implementation of the other accessor. You can also useSUPERto make the access mode of the property less restrictive. - SET ( parameter-definition[ , array-index-parameter] ) : set-logic END [ SET ].
- A coded
SETaccessor (defined with an implementation). The value written to the property is assigned to the parameter specified by parameter-definition, which has the following syntax:[ INPUT ]parameter-name AS {primtive-type-name|[ CLASS ]object-type-name}The
INPUTparameter (parameter-name) holds the value being written to the property as the property is being set, but does not by itself set the property value. The data type that you specify for the parameter (primitive-type-name or object-type-name) must match the data type you have defined for the property. How the property value is set depends entirely on the statements in set-logic. These statements can include any number and types of statements that are valid for a method. Thus, set-logic statements can access the value being written to the property (parameter-name), and they can read or write the value of property default memory (property-name) or the values of any other data elements that are available to the accessor like any method in the class definition. However, for the property value to be set, at least one statement must assign the value of parameter-name to either property-name or to some other data element maintained by theSETaccessor. If the property is defined as static, set-logic statements can access only other static members defined within the current class hierarchy in addition to its default memory and local accessor data; instance members defined within the current class hierarchy are inaccessible. However, if the property is defined as an instance member, set-logic statements can access static members as well as other instance members.If the property is defined as an array using the
EXTENToption, the set-logic always works on one element of the array at a time, whether the array is written with or without a subscript. If the array is written without a subscript, set-logic executes once for each element in the property array. If specified, the optional array-index-parameter passes the subscript value to the set-logic for the current element being accessed. This is the syntax:[ INPUT ]array-index-name AS { INTEGER | INT64 }The array-index-name provides a name for the index parameter, which can have one of the specified integer data types. Whatever retrieval operation you code for the set-logic can then access the appropriate array element of the property default memory by using array-index-name as the array subscript (property-name
[array-index-name]).Note: Any statement in set-logic that reads property-name reads the value returned by the propertyGETaccessor. However, any set-logic statements that assign a value to property-name directly assign that value to property default memory.If a statement in set-logic raises an
ERRORcondition that is not handled using theNO-ERRORoption, the condition can be handled by the associated block according to itsON ERRORdefinition or the presence of an appropriateCATCHstatement. If the associated block is the accessor, itself, it can also handle the condition according to the defaultON ERRORhandling for method and procedure blocks or according to any specifiedROUTINE-LEVEL ON ERROR UNDO, THROWstatement.A RETURN ERROR or
UNDO, THROWin >set-logic that raisesERRORbeyond theSETaccessor block, raises theERRORcondition on the statement that is reading the property. Any data elements (including property default memory) that have been changed by set-logic retain their latest values or revert to their values before this statement executed, depending on their respectiveNO-UNDOsettings. Any optionalRETURN-VALUEsetting or error object can be appropriately accessed after control returns from the statement that is writing the property. For more information on handling errors returned from properties, see Raise and handle error conditions.
The following example shows a property definition
and its access within another sample class definition, acme.myObjs.CreditObj:
|
In this definition, the property CustCreditLimit is publicly readable, but writable only within the definition of
CreditObj or any subclass that might be defined. (The
CreditObj of a particular instance is also writable from
another instance of the same class or subclass.) This property definition uses its default
memory (DECIMAL) to store the property value and provides
an implementation for only one of its accessors (the SET),
which interacts with the Customer buffer currently
available in CreditObj (initialization code not shown).
Note that the SET accessor throws an error object for an
application condition and the public method, CheckCustCredit( ), defined in the same class writes the property value that
might trigger the error. Because the property is defined as NO-UNDO, the SET value for the property
default memory is retained, even when it raises ERROR in
the caller. Any error object is then automatically thrown out of the SET accessor because the class is defined with a ROUTINE-LEVEL ON ERROR UNDO, THROW statement.
For more information on accessing properties, see Access data members and properties. For more information on handling property error conditions, see Raise errors within a property.