robjectoopr-s4

Correct way to inherit an S4 object in another S4 Object in R


I want to create an S4 class with one slot as another S4 class. Following is the simplified version of the code,

Definition of Class 1

setClass(
 "class1",
    representation(
     class1_vector = "character",
     class1_vector2 = "numeric"
   )
)

Definition of another class that inherits Class 1

setClass(
 "class2",
 
 # Inheritance of class 1
 contains = c("class1"),

 # Slots
   representation(
        class1_object = "class1", # Slot of Class 1
        class2.frame = "data.frame"
    )
)

I only want to create object 2 using a function as follows. This function only asks for slots for class-2

some.function <- function(df){

    # Create an object for class1
    object.class1 <- new("class1",
       class1_vector = as.character(NULL),
       class1_vector2 = as.numeric(NULL)
                     )

   # Create an Object for class2 with the object of class1
    object.class2 <- new("class2",
        class1_object = object.class1,
        class2.frame = df)

   return(object.class2)
}

Returned Object

obj <- some.function(df = data.frame(colName = c(1,2,3)))

Upon viewing the obj in R-studio, I see two additional slots of class1 in obj. class1_vector and class1_vector2 are the slots from Class1. enter image description here

why do they exist as a slot of both Class1 and Class2? I want to make the object with all slots of Class1.Object as null in the beginning.

Is there a correct way to do this? Where I am going wrong?

Thanks for the help.


Solution

  • The problem is that you are defining class2 as a type of class1, since by specifying contains = c("class1") you are specifically telling setClass that you want class2 to inherit the slots from class1. In other words, you want class2 to have the slots called class1_vector and class1_vector2.

    But in addition, your definition is specifying that you want class2 to have a slot that contains a class1 object. This is nothing to do with inheritance, and nothing to do with the contains parameter of setClass. You simply have one class in the member slot of another class.

    If all you want is for class2 to contain a class1 object in a slot, simply remove contains = c("class1") from the definition of class2

    setClass(
      "class2",
      
      # Slots
      representation(
        class1_object = "class1", # Slot of Class 1
        class2.frame = "data.frame"
      )
    )
    

    So now when you do

    obj <- some.function(df = data.frame(colName = c(1,2,3)))
    

    You get this:

    View(obj)
    

    enter image description here