S3 系统是宽泛且灵活的,同类的 S3 对象也可能有不同的成员。但是,对于 S4 系统,
就不会发生,也就是说,当我们创建一个属于某类的 S4 对象实例时,不能任意添加不在类
表示中的字段。
举个例子,在创建一个新的 Product 类的对象实例时,我们不能添加 volume 字段:
bottle <- new("Product", name = "Bottle",
price = 3, inventory = 100L, volume = 15)
## Error in initialize(value, ...): invalid name for slot of class "Product":
volume
相反,添加只能通过合适的继承来完成。我们需要创建一个新类,它包含(或继承自)
原始类。在这个例子中,我们定义一个 Container 类,它继承 Product 类,而且有一个
新的名为 volume 的数值字段:
setClass("Container",
representation(volume = "numeric"),
contains = "Product")
因为 Container 类继承 Product 类,所以任何 Container 类的对象实例都有
Product 类的所有字段,可以使用 getSlots( )进行查看:
getSlots("Container")
## volume name price inventory
## "numeric" "character" "numeric" "integer"
现在,我们创建一个含有 volume 字段的 Container 类对象实例:
bottle <- new("Container", name ="Bottle",
price = 3, inventory = 100L, volume = 15)
要注意,在创建 Container 类的对象实例时,Product 类的验证函数仍起作用:
bottle <- new("Container", name ="Bottle",
price = 3, inventory = -10L, volume = 15)
## Error in validObject(.Object): invalid class "Container" object: inventory
must be non-negative
因此,执行检查可以确保 Product 类字段的有效性,但是检查对 Container 类独有
的字段不起作用:
bottle <-new("Container", name = "Bottle",
price = 3, inventory = 100L, volume = -2)
我们为 Product 类定义了验证函数,同样,也可以为 Container 类定义一个验证函数:
validate_container <- function(object) {
errors <- c(
if (length(object@volume) != 1)
"Length of volume must be 1",
if (object@volume <= 0)
"volume must be positive"
)
if (length(errors) == 0) TRUE else errors
}
这样,我们就可以使用这个验证函数重新定义 Container 类:
setClass("Container",
representation(volume = "numeric"),
contains ="Product",
validity = validate_container)
注意到,不需要在validate_container( )中调用validate_product( ),因为两
个验证函数会被依次调用来确保所有位于继承链上的类都被(自己的验证函数)适当地检查了。
当然,也可以在验证函数中添加一些文本打印代码,以此确保在创建一个Container 类的对象
实例时,validate_product( )总是比validate_container( )先被调用:
bottle <- new("Container", name = "Bottle",
price = 3, inventory = 100L, volume = -2)
## Error in validObject(.Object): invalid class "Container" object: volume
must be positive
bottle <- new("Container", name = "Bottle",
price = 3, inventory = -5L, volume = 10)
## Error in validObject(.Object): invalid class "Container" object:
inventory must be non-negative

S4 继承的更多相关文章

  1. S4 对象系统

    上一节中,我们介绍了 S3 系统.与大多数其他编程语言的面向对象系统不同,与那些类被定义为固定结构,且随着程序编译有确定的方法分派的系统相比,S3 系统显得非常不严谨.当我们定义一个 S3 类时,几乎 ...

  2. Alignment And Compiler Error C2719 字节对齐和编译错误C2719

    Compiler Error C2719 'parameter': formal parameter with __declspec(align('#')) won't be aligned The ...

  3. JavaSE基础:泛型

    泛型 1.引入 情景模式描述,假设完成一个学生的成绩的情况: 整数: math=80,english=70 小数: math=85.6,englisth=77.8 字符串: math="66 ...

  4. 【一次面试】再谈javascript中的继承

    前言 面向对象编程是每次面试必问的知识点,而前端js如何实现继承每次命中率高达80% 这不,近两天我们面试时候,同事就问道面试者此问题,但是,不论之前自己做的回答,还是面试者的回答,基本都不太令人满意 ...

  5. 理解C#中的继承

    继承 1.创建子类对象的时候,在子类对象中会为子类对象的字段开辟空间,也会为父类对象的所有字段开辟空间.只不过父类私有的成员访问不到而已. 2.base关键字可以调用父类的非私有成员. 3.子类的访问 ...

  6. 程序设计实习MOOC / 继承和派生——编程作业 第五周程序填空题1

    描述 写一个MyString 类,使得下面程序的输出结果是: 1. abcd-efgh-abcd- 2. abcd- 3. 4. abcd-efgh- 5. efgh- 6. c 7. abcd- 8 ...

  7. C++中的继承详解(3)作用域与重定义,赋值兼容规则

    作用域与同名隐藏 一样的,先上代码 1 class A 2 { 3 public: 4 int a_data; 5 void a() 6 { 7 cout << "A" ...

  8. C++中的继承(3)作用域与重定义,赋值兼容规则

    作用域与重定义(同名隐藏) 一样的,先上代码 1 class A 2 { 3 public: 4 int a_data; 5 void a() 6 { 7 cout << "A& ...

  9. 详谈Javascript类与继承

    本文将从以下几方面介绍类与继承 类的声明与实例化 如何实现继承 继承的几种方式 类的声明与实例化 类的声明一般有两种方式 //类的声明 var Animal = function () { this. ...

随机推荐

  1. Thinkphp自定义工具类的使用!

    在使用Thinkphp做开发的时候,很多时候会用到一些自己写的类,为了方便管理,可以把这些类,单独放到一个文件里. 这就是自定义工具类: 首先在 Application 目录下新建 Component ...

  2. postgresql----LIKE和SIMILAR TO

    LIKE和SIMILAR TO都支持模糊查询,另外SIMILAR TO还支持正则表达式查询.模糊查询中有两个重要的符号:下划线'_'匹配任意单个字符,百分号'%'匹配任意多个字符,可以是0个,如果想匹 ...

  3. poj3345 Bribing FIPA【树形DP】【背包】

    Bribing FIPA Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 5910   Accepted: 1850 Desc ...

  4. Oracle AWR之-enq: TX - allocate ITL entry

    今天收到压力测试期间awr报告,测试人员要我看看数据库是否有可以优化的地方,数据库服务器配置信息:CPU:32*8,内存:480g 单实例数据库:oracle 11.2.0.4.具体分析过程如下: 可 ...

  5. Python爬虫框架Scrapy实例(一)

    目标任务:爬取腾讯社招信息,需要爬取的内容为:职位名称,职位的详情链接,职位类别,招聘人数,工作地点,发布时间. 一.创建Scrapy项目 scrapy startproject Tencent 命令 ...

  6. Python开发【模块】:邮件

    邮件 1.简单发送 settings.py配置: import os import sys,string from bin.start import BASE_DIR # 日志存放地址 RUN_LOG ...

  7. Python开发【Django】:CMDB基础

    浅谈ITIL TIL即IT基础架构库(Information Technology Infrastructure Library, ITIL,信息技术基础架构库)由英国政府部门CCTA(Central ...

  8. Openstack(十七)部署快存储cinder

    官方部署文档:https://docs.openstack.org/ocata/zh_CN/install-guide-rdo/cinder.html OpenStack的存储组件—Cinder和Sw ...

  9. controller中两个方法之间共享一个变量LinkedHashMap

    1:引用传递,创建一个变量,给两个线程都传递进去. 2:静态修饰 static  通过该修饰符说明,该变量只有一份,  所有线程共用一份. 例如下面的htmlidMap通过static变量修饰, up ...

  10. ScyllaDB - 基础部署

    基础环境 操作系统: CentOS 7.2: 集群节点(虚拟机):172.16.134.15 ~ 17: 基础准备 安装依赖和卸载 abrt ( abrt 和 coredump 配置冲突 ): sud ...