Читать книгу The Big R-Book - Philippe J. S. De Brouwer - Страница 226
Hint
ОглавлениеIt is possible to leave the input type undecided by not providing a type in the list environment. This could look like this:
setRefClass(“account”, fields = list(holder, # accepts all types branch, # accepts all types opening_date = “Date” # dates only ) )
Let us now explore this object that was returned by the function setRefClass()
.
isS4(account) ## [1] TRUE # account is S4 and it has a lot more than we have defined: account ## Generator for class “account”: ## ## Class fields: ## ## Name: ref_number holder branch ## Class: numeric character character ## ## Name: opening_date account_type ## Class: Date c haracter ## ## Class Methods: ## “field”, “trace”, “getRefClass”, “initFields”, ## “copy”, “callSuper”, “.objectPackage”, “export”, ## “untrace”, “getClass”, “show”, “usingMethods”, ## “.objectParent”, “import” ## ## Reference Superclasses: ## “envRefClass”
The object returned by setRefClass
(or retrieved later by getRefClass
) is called a generator object. This object automatically gets the following methods.
generator object
new to create instances of the class. Its arguments are the named arguments specifying initial values for the fields;
methods to add methods or modify existing;
help to get help about the methods;
fields to get a list of attributes (fields) of that class;
lock to lock the named fields so that their value can only be set once;
accessors sets up accessor-methods in form of getxxx and setxxx (where “xxx” is replaced by the field names).
Refclass objects are mutable, or in other words, they have reference semantics. To understand this, we shall create the current account class and the investment account class.
custBank <- setRefClass(“custBank”, fields = list(name = “character”, phone = “character” ) ) invAccount <- setRefClass(“invAccount”, fields = list(custodian = “custBank”), contains = c(“account”) # methods go here )
Let us now come back to the current account and define it while adding some methods (though as we will see later, it is possible to add them later too).
# Definition of RC object currentAccount currAccount <- setRefClass(“currentAccount”, fields = list(interest_rate = “numeric”, balance = “numeric”), contains = c(“account”), methods = list( credit = function(amnt) { balance <<- balance + amnt }, debet = function(amnt) { if (amnt <= balance) { balance <<- balance - amnt } else { stop(“Not rich enough!”) } } ) ) # note how the class reports on itself: currAccount ## Generator for class “currentAccount”: ## ## Class fields: ## ## Name: ref_number holder branch ## Class: numeric character character ## ## Name: opening_date account_type interest_rate ## Class: Date character numeric ## ## Name: balance ## Class: numeric ## ## Class Methods: ## “debet”, “credit”, “import”, “.objectParent”, ## “usingMethods”, “show”, “getClass”, “untrace”, ## “export”, “.objectPackage”, “callSuper”, “copy”, ## “initFields”, “getRefClass”, “trace”, “field” ## ## Reference Superclasses: ## “account”, “envRefClass”