Abbreviated introduction based on the vignette

To install (it’s now on CRAN):

install.packages("S7")
library(S7)
dog <- new_class("dog", properties = list(
  name = class_character,
  age = class_numeric
))
dog


#> <S7_class>
#> @ name  :  dog
#> @ parent: <S7_object>
#> @ properties:
#>  $ name: <character>          
#>  $ age : <integer> or <double>

Note the class_character, these are S7 classes corresponding to the base classes.

Now to use it to create an object of class dog:

lola <- dog(name = "Lola", age = 11)
lola

#> <dog>
#>  @ name: chr "Lola"
#>  @ age : num 11

Properties can be set/read with @, with automatic validation (‘safety rails’) based on the type!


lola@age <- 12
lola@age

#> 12

lola@age <- "twelve"

#> Error: <dog>@age must be <integer> or <double>, not <character>

Note the helpful error message!

Like S3 (and S4) S7 has generics, implemented with new_generic and method for particular methods:

speak <- new_generic("speak", "x")

method(speak, dog) <- function(x) {
  "Woof"
}
  
speak(lola)

#> [1] "Woof"

If we have another class, we can implement the generic for that too:

cat <- new_class("cat", properties = list(
  name = class_character,
  age = class_double
))
method(speak, cat) <- function(x) {
  "Meow"
}

fluffy <- cat(name = "Fluffy", age = 5)
speak(fluffy)

#> [1] "Meow"

Helpful messages:

speak

#> <S7_generic> speak(x, ...) with 2 methods:
#> 1: method(speak, cat)
#> 2: method(speak, dog)

“most usage of S7 with S3 will just work”

method(print, cat) <- function(...) {
  print("I am a cat.")
}

print(fluffy)
#> "I am a cat"

For validators, inheritance, dynamic properties and more, see the vignette!