泛型函数:
一组不同的函数定义同一个通用名称,关联不同对象,处理不同对象表现不同行为.(R的函数重载机制),R中S3对象的方法和S4类的方法是通过泛型函数机制关联到目标,方法通过S3和S4泛型函数机制绑定到S3对象和S4类上的.

S3对象:是基于泛型函数的面向对象机制.S3对象可看作是一个list并有一个名为class的属性.S3没有正式的类型定义.

> t<-structure(1,class="foo") #返回一个S3类
 > t
 [1] 1
 attr(,"class")
 [1] "foo"

 > p=list(a=1,b=2) #生成列表,为对象class属性赋值.构造S3对象.
 > class(p)="foo"
 > p
 $a
 [1] 1
 $b
 [1] 2
 attr(,"class")
 [1] "foo"

 S3泛型函数:基于泛型的面向对象,通过S3泛型函数分派.
 > bar<-function(o) UseMethod("bar")#bar函数调用UseMethod("bar"),UseMethod依据o的类,search对应的bar.*方法,没有找到如果存在bar.default则调用,否则报错.
 > bar.default<-function(o) "default"     
 > bar.foo<-function(o) "foo"               
 > bar(t)      #调用了bar.foo
 [1] "foo"
 > bar(123)    #调用了bar.default
 [1] "default"
 > bar(p)
 [1] "foo"
 > bar<-function(o=123) UseMethod("bar",o)#指定bar默认对象
 > bar() #默认使用了bar(123)
 [1] "default"
 > bar<-function(o=t) UseMethod("bar",o)
 > bar()#默认使用了bar(t)
 [1] "foo"
 S3面向对象机制,是一系列命名规则构造的,generic.class命名方式决定了其行为.分派过程是一种按照命名规则搜索对应函数的过程.
 查找隐藏S3方法,可以得到隐藏在泛型方法后面的普通方法即信息
 > getAnywhere(bar.foo)
 >  getAnywhere(bar.foo)
 A single object matching ‘bar.foo’ was found
 It was found in the following places
   .GlobalEnv
   registered S3 method for bar
 with value
 function(o) "foo"
 > f=getS3method(f="bar",class="foo")
 > f
 function(o) "foo"
 > f(1)
 [1] "foo"
 构建一个S4类foo,new(foo),S3泛型函数bar调用了bar.foo,S3泛型函数只是基于命名规则的查找,任何class属性为"foo"的对象都会由UseMethod查找到bar.foo.
 > setClass("foo",representation = (data="numeric"))
 > l=new("foo")
 > l
 An object of class "foo"
 numeric(0)
 > class(l)
 [1] "foo"
 attr(,"package")
 [1] ".GlobalEnv"
 > bar(l) #bar.foo
 [1] "foo"



S4泛型函数:S4使用S4泛型函数机制分派方法,S4泛型不是基于命名固定规则查找。而是通过注册将某个对象及其对应处理的方法关联起来.
将普通函数注册为泛型函数,原普通函数可以被重载。原普通函数是泛型函数的基本框架,当处理对象的类别没有重载的方法,则使用的是原普通函数,有重载则调用重载函数.

> series<-function(o){"series"} #定义一个普通函数
 > setGeneric("series") #注册为泛型函数
 > series
 standardGeneric for "series" defined from package ".GlobalEnv"
 function (o) 
 standardGeneric("series")
 <environment: 0x4fc9388>
 Methods may be defined for arguments: o
 Use  showMethods("series")  for currently available ones.
 > showMethods(series)
 Function: series (package .GlobalEnv)
 o="ANY"
 > series()
 "series"
 > series(123)
 [1] "series"
 > series(p) #p is S3对象 class(p) is foo
 [1] "series"
 #对象没有指定函数,默认使用了series自身,并将类型信息写在了广义函数中
 > showMethods(series)
 Function: series (package .GlobalEnv)
 o="ANY"
 o="foo"
     (inherited from: o="ANY")
 o="missing"
     (inherited from: o="ANY")
 o="numeric"
     (inherited from: o="ANY")
     
 #设置了foof,food类型,及其自定义的关联函数.自己设置的没有(inherited from: o="ANY")
 > setMethod(series,signature = c("foof"),definition = function(o){"foof"})
 > setMethod(series,signature = c("food"),definition = function(o){"food"})
 > showMethods(series)
 Function: series (package .GlobalEnv)
 o="ANY"
 o="food"
 o="foof"
 #定义两个S3对象,设置为food类,和foof类
 > a=1
 > class(a)="food"
 > b=1
 > class(b)="foof"
 #S4泛型series依据传入对象的class属性,在自己的方法设置列表中寻找对应类别以及对应的函数对象,执行重载函数。
 #S4泛型也是基于class属性查找对应函数.
 > series(a)
 [1] "food"
 > series(b)
 [1] "foof"
 #def参数在注册广义函数时,同时定义函数原型==先定义原型+后注册泛型函数
 > setGeneric("pq",def=function(o){"pq"})
 [1] "pq"
 > pq
 standardGeneric for "pq" defined from package ".GlobalEnv"
 function (o) 
 standardGeneric("pq")
 <environment: 0x5118ac8>
 Methods may be defined for arguments: o
 Use  showMethods("pq")  for currently available ones.
 > pq()
 [1] "pq"




S4对象:实现了oop机制。有基本的类型,继承,封装等。S4对象从基本类new构造,有基本的类型。S4对象的方法不同于C++等语言,定义类的方法。而是通过泛型范数机制。定义一个泛型函数,然后设置特定类及其特定方法。将泛型范数关联到对象。方法绑定对象,不是C++等语言的对象.方法。因此R中"."不是运算符,是一个普通字符,可以出现在符号(变量名)中。data.frame()表示名为"data.frame"的函数而不是data对象的frame函数.

> setClass("l",representation(data="numeric"))
 > setClass("fp",representation(d="numeric"),contains = c("l")) #contains指定继承
 > f=new("fp") #new对象,未赋初值
 > f
 > f@d=1
 > f@data=2
 > f
 An object of class "fp"
 Slot "d":  
 [1] 1
 Slot "data": #继承自l
 [1] 2
 #设置类的initialize泛型函数,initialize相当于构造函数.
 > setMethod(initialize,signature = c("fp"),definition = function(.Object){print("hello");.Object})
 [1] "initialize"
 attr(,"package")
 [1] "methods"
 > ff=new("fp")
 [1] "hello"
 为一批类指定某个方法时,可以为这批类指定一个虚类为父类.然后为虚父类,写一个方法.(类比java接口)
 > setClass("a",representation(data="numeric"))
 > setClass("b",representation(data="numeric"))
 > setClassUnion("vb",c("a","b")) #指定a,b虚父类为vb
 > new("vb")
 Error in new("vb"):无法从虚拟类别("vb")中产生对象 #虚类无法new
 > setMethod(series,signature = c("vb"),function(o){"virtual base"}) #为vb指定方法
 > showMethods(series)
 Function: series (package .GlobalEnv)
 o="ANY"
 o="food"
 o="foof"
 o="vb"
 > a1=new("a")
 > b1=new("b")
 > series(a1)       #调用了vb的方法.
 [1] "virtual base"
 > series(b1)
 [1] "virtual base"
 > setMethod(series,signature = c("a"),function(o){"a"}) #重写a的series方法
 > showMethods(series)
 Function: series (package .GlobalEnv)
 o="a"
 o="ANY"
 o="food"
 o="foof"
 o="vb"
 > series(a1) #此时调用了a的series方法,覆盖了虚父类的方法
 [1] "a"
 > series(b1)
 [1] "virtual base"
 > showMethods(series)
 Function: series (package .GlobalEnv)
 o="a"
 o="ANY"
 o="b"
     (inherited from: o="vb") #继承自vb
 o="food"
 o="foof" 
o="vb"