[R] R.oo data members / inheritance

Henrik Bengtsson hb at biostat.ucsf.edu
Sat Aug 27 04:14:10 CEST 2011


Hi.

On Fri, Aug 26, 2011 at 8:58 AM, Ben qant <ccquant at gmail.com> wrote:
> If someone is able, can you tell me if there is a better way to do this?
> More specifically, do I have to rewrite all of the data members stuff  and
> extend stuff of parent class in the child class?

No.

> See below. Thanks in
> advance!
>
> Example 1:
>
> setConstructorS3("ClassA", function(A,x) {
>  if(missing(A))A=15;
>  if(missing(x))x=NA;
>  extend(Object(), "ClassA",
>    .size = A,
>    .x=x
>  )
> })
> setMethodS3("getSize", "ClassA", function(this,...) {
>  this$.size;
> })
> setMethodS3("getX", "ClassA", function(this,...) {
>  this$.x;
> })
>
> setConstructorS3("ClassB", function(A,x,bData) {
>  if(missing(bData))bData = NA;
>  extend(ClassA(), "ClassB",
>    .bData = bData
>  )
> })

The key is to understand that that inner ClassA() is a just regular
function call that returns an object of class "ClassA" [with full
class attribute vector c("ClassA", "Object")].  Since it is a regular
function you can pass arguments to it as well, so in your case just
do:

setConstructorS3("ClassB", function(A,x,bData) {
  if(missing(A))A=15;
  if(missing(x))x=NA;
  if(missing(bData))bData = NA;
  extend(ClassA(A=A, x=x), "ClassB",
    .bData = bData
  )
})

or more generic:

setConstructorS3("ClassB", function(..., bData) {
  if(missing(bData)) bData = NA;
  extend(ClassA(...), "ClassB",
    .bData = bData
  )
})

Personally, I also try to avoid using missing() and instead using
default argument values, i.e.

setConstructorS3("ClassA", function(A=15, x=NA) {
  extend(Object(), "ClassA",
   .size = A,
   .x=x
 )
})

setConstructorS3("ClassB", function(..., bData=NA) {
  extend(ClassA(...), "ClassB",
    .bData = bData
  )
})

which also makes things cleaner.

Hope this helps

/Henrik
(author of R.oo)

> setMethodS3("getBData", "ClassB", function(this,...) {
>  this$.bData;
> })
>
> Usage:
>> b = ClassB(13,100,6)
>> b$getSize()          # I expected to get 13.
> [1] 15
>> b$getBData()
> [1] 6
>> b$getX()
> [1] NA            # Same thing here. I expected 100.
>
>
> I corrected it by rewriting the ClassA data member defaults and the ClassA
> extend() stuff within the ClassB class.
>
> Example 2:
>
> setConstructorS3("ClassA", function(A,x) {
>  if(missing(A))A=15;
>  if(missing(x))x=NA;
>  extend(Object(), "ClassA",
>    .size = A,
>    .x=x
>  )
> })
> setMethodS3("getSize", "ClassA", function(this,...) {
>  this$.size;
> })
> setMethodS3("getX", "ClassA", function(this,...) {
>  this$.x;
> })
>
> setConstructorS3("ClassB", function(A,x,bData) {
>  if(missing(bData))bData = NA;
>  if(missing(A))A=15;                          #added
>  if(missing(x))x=NA;                             #added
>  extend(ClassA(), "ClassB",
>    .bData = bData,
>    .x=x,                                           #added
>    .size=A                                         #added
>  )
> })
> setMethodS3("getBData", "ClassB", function(this,...) {
>  this$.bData;
> })
>
>> b = ClassB(13,100,6)
>> b$getSize()
> [1] 13
>> b$getBData()
> [1] 6
>> b$getX()
> [1] 100
>
> Thanks for your help!
>
> Ben
>
>        [[alternative HTML version deleted]]
>
> ______________________________________________
> R-help at r-project.org mailing list
> https://stat.ethz.ch/mailman/listinfo/r-help
> PLEASE do read the posting guide http://www.R-project.org/posting-guide.html
> and provide commented, minimal, self-contained, reproducible code.
>



More information about the R-help mailing list