What is object oriented programming? While definitions for OOP abound without clear agreement, OOP languages typically focus programers on the actors/objects(none) of a problem rather than the actions/procedures(verbs), by using a common set of language features, including: 1) Encapsulation data and code - the data and the code that manages that data are kept together by the language( in classes, models or clusters, etc.) Implicitly, this includes the notion of class definitions and class instances. 2) Information hiding - an exposed API with a hidden implementation of code and data; encourages programming by contract 3) Abstraction and Inheritance - so that similarities and difference in the underlying model/data/code/logic for related objects can be grouped & reused 4) Dynamic dispatch - more than one method with the same name - where the method used is selected at compile or run-time by the class of the object and also the class of the method parameter types and their arity (argument number). Four R Mechanisms with some OOP features 1) Lexical scoping - simple - encapsulation - mutability - information hiding, BUT not real classes - no inheritance 2) S3 classes - multiple dispatch on class only - inheritance, BUT just a naming convention - no encapsulation - no information hiding - no control over use - no consistency checks - easy to abuse 3) S4 formal classes - multiple inheritance - multiple dispatch - inheritance - type checking, BUT no information hiding - verbose and complex to code - lots of new terms - immutable classes only 4) R5 reference classes - built on S4 - mutable ( more like Java, C++) - type checking - multiple inheritance, BUT no information hiding - inconsistent with R's functional programming heritage Note: None of R's OOP systems are as full featured or as robust as Java or C++. What are S3 classes # An S3 class is any R object to which a class attribute has been attached. S3 classes - key functions class(x) class(x) <-'name' methods('method') UseMethod('method', x) NextMethod() Class code example c.list <- list(hrs=12, mins=0, diem='am') clas(c.list) class(c.list) clock <- structure(list(hrs=12, mins=0, diem="am"), .Names= c("hrs", "mins", "diem"), class = "clock") c.list <- unclass(c.list) attr(c.list, 'class') Dynamic dispatch - UseMethod() # the UseMehod for print already exists: # print <- function(x) UseMehod('print', x) print.clock <- function(x) { cat(x$hrs); cat(':') cat(sprintf('%02d', x$mins)); cat(' '); cat(x$diem); cat('\n'); } print(c.list) methods('print') Inheritance dispatch - NExtMethod() # S3 classes allow for a limited form of class inheirtance fo the purposes of method dispatch. Try the following code: sound <- function(x) UseMehod('sound', x) sound.animal <- function(x) NextMethod() sound.human <- function(x) 'conversation' sound.cat <- function(x) 'meow' sound.default <- function(x) 'grunt' Cathy <- list(legs=4) class(Cathy) <- c('animal', 'cat') Harry <- list(legs=4) class(Leroy) <- c('animal', 'llama') sound(Cathy) sound(Harry) sound(Leroy) Should I use S3 or S4 or R5? S3: for amall/medium projects; S4 for larger; R5 if mutability is necessaryR5 Reference Classes Summary of some key class mechanisms 1) create/get object-generator: gen <- setRefClass('name', fields=, contains=, methods=, where,...) enf <- getRefClass('name') - generator gen$lock('fieldName') - lock a field gen$help(topic) - get help on the class gen$methods(...) - add methods to class gen$methods() - get a list of methods gen$fileds() - get a list of fields gen$accessors(...) - create get/set fns 2) generator object used to get instance: inst <- gen$new(...) - instantiation parameters passed to initialize(...) inst$copy(shallow=F) - copy instance inst$show() - called by print inst$field(name, value) - set inst$field(name) - get is(inst 'envReflass') - is R5 test [envRefClass is the super class for R5] 3) code from within your methods initialize(...) instance initializer finalize() - called by garbage collector .self -reference to the self instance .refClassDef -the class definition methods::show() - call the show function callSuper(...) - call the same method in the super class .self$classVariable <- localVariable classVariable <<- local Variable globalVariable <<- localVariable .self$classVariable <- localVariable .self$field(clasVar, localVar) # set .self$field(classVar, localVar) # get Trap: very easy to confuse <- and <<- Trap: if x is not a class field; x<<- var assigns to x in global environment Field list - code sample A <- setRefClas('A', fields = list( # 1. typed, instance filed: exampleVar1 = 'character', # 2. instance file with accessor: ev2.private='character', exampleVar2 = function(x) { if(!missing(x)) ev2.private <<- x ev2.private } ),methods = list( initialize=function(c='default') { exampleVar1 <<- c exampleVar2 <<- c } ) ) instA <_ A$new('instnce of A'); str(instA) Inheritance code sample Animal <- setRefClass('Animal', # virtual super class contains = list('VIRTUAL'), fields = list(i.am = 'character', noiseMakes = 'character'), methods = list(initialize=function(i.am='unknown', noiseMakes = 'unknown') { .self$i.am <-i.am .self$noiseMakes <- noiseMakes }, show=function(){ cat('I am a'); cat(i.am) cat('. I make this noise:') cat(noiseMakes); cat('\n') } ) ) Cat <- setRefCalss('Cat', contains = list('Aninmal'), methods = list( initialize=function() callSuper('cat', 'meow'), finalize=function() cat('Another cat passes.\n') ) ) Dog <- setRefClass('Dog', contains = list('Animal'), methods = list( initialize=function() callSuper('dog', 'woof'), show = function() { callSuper() cat('I like to chew shoes. \n') } ) ) mongrel <- Animal$new() fido = Dog$new(); felix =Cat$new() print(fido); print(felix) felix <- NULL gc() What's neither C++ nor Java 1) No information hideing. Everthing is public and modifiable. (But the R package mechanism helps here). 2) No static class fields. 3) Not as developed or robust OOP space. Tips(safer coding practices) and Traps 1) use named filed list to type variables 2) use accessor methods in the filed list to maintain class type & state validity 3) Trap: methodName <- function() in methods list. Use = ( it's a named list!) 4) Trap: cant use enclosing environments within R5 classes as they are in one).
Friday, November 20, 2015
R Basics 11 - OOP and R5
Labels:
R
Subscribe to:
Post Comments (Atom)
Blog Archive
-
▼
2015
(43)
-
▼
November
(18)
- Similarity Calculation 5 - Mutual Information Usin...
- Similarity Calculation 4 - Naive Bayes Using SQL a...
- Similarity Calculation 3 - Gini/Efficiency Similar...
- Similarity Calculation 2 - Cosine Similarity Using...
- Similarity Calculation 1 - Jaccard Similarity Usin...
- R Basics 12 - Enviromnetnts, Frames and the Call S...
- R Basics 11 - OOP and R5
- R Basics 10 - Avoiding For-Loops
- R Basics 9 - Writing Functions
- R Basics 8 - Tips and Traps
- R Basics 7 - Factors
- R Basics 6 - Matrices and Arrays
- R Basics 5 - Data Frames
- R Basics 4 - Lists
- R Basics 3 - Atomic Vectors
- R Basics 2 - Basic List of Useful Functions in R
- R Basics 1 - Brief Introduction to Language Elemen...
- Part 2: Frequent Item Sets Using SQL
-
▼
November
(18)
No comments:
Post a Comment