R语言泛型函数及S3,S4对象机制

泛型函数:
一组不同的函数定义同一个通用名称,关联不同对象,处理不同对象表现不同行为.(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 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”)

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”)

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”

R对象的属性和槽:
R对象的槽是创建类时自定义的成员变量.R对象的属性非自定义,R内部定义的,描述了对象代表的内容,以及R解释对象的方式。常见属性有:class,names,dim…。对象槽的名称不能与某些属性名相同,so R对象同时具有槽和属性.

a<-c(1,2)
a
[1] 1 2
names(a)
NULL
names(a)<-c(‘a’,’b’) #为names属性赋值,使a称为命名向量
a
a b
1 2
str(a)
Named num [1:2] 1 2
- attr(*, “names”)= chr [1:2] “a” “b”

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值