S4 继承
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 继承的更多相关文章
- S4 对象系统
上一节中,我们介绍了 S3 系统.与大多数其他编程语言的面向对象系统不同,与那些类被定义为固定结构,且随着程序编译有确定的方法分派的系统相比,S3 系统显得非常不严谨.当我们定义一个 S3 类时,几乎 ...
- Alignment And Compiler Error C2719 字节对齐和编译错误C2719
Compiler Error C2719 'parameter': formal parameter with __declspec(align('#')) won't be aligned The ...
- JavaSE基础:泛型
泛型 1.引入 情景模式描述,假设完成一个学生的成绩的情况: 整数: math=80,english=70 小数: math=85.6,englisth=77.8 字符串: math="66 ...
- 【一次面试】再谈javascript中的继承
前言 面向对象编程是每次面试必问的知识点,而前端js如何实现继承每次命中率高达80% 这不,近两天我们面试时候,同事就问道面试者此问题,但是,不论之前自己做的回答,还是面试者的回答,基本都不太令人满意 ...
- 理解C#中的继承
继承 1.创建子类对象的时候,在子类对象中会为子类对象的字段开辟空间,也会为父类对象的所有字段开辟空间.只不过父类私有的成员访问不到而已. 2.base关键字可以调用父类的非私有成员. 3.子类的访问 ...
- 程序设计实习MOOC / 继承和派生——编程作业 第五周程序填空题1
描述 写一个MyString 类,使得下面程序的输出结果是: 1. abcd-efgh-abcd- 2. abcd- 3. 4. abcd-efgh- 5. efgh- 6. c 7. abcd- 8 ...
- C++中的继承详解(3)作用域与重定义,赋值兼容规则
作用域与同名隐藏 一样的,先上代码 1 class A 2 { 3 public: 4 int a_data; 5 void a() 6 { 7 cout << "A" ...
- C++中的继承(3)作用域与重定义,赋值兼容规则
作用域与重定义(同名隐藏) 一样的,先上代码 1 class A 2 { 3 public: 4 int a_data; 5 void a() 6 { 7 cout << "A& ...
- 详谈Javascript类与继承
本文将从以下几方面介绍类与继承 类的声明与实例化 如何实现继承 继承的几种方式 类的声明与实例化 类的声明一般有两种方式 //类的声明 var Animal = function () { this. ...
随机推荐
- Android 让GridView的高度为Wrap_content根据内容自适应高度
From:http://www.jayway.com/2012/10/04/how-to-make-the-height-of-a-gridview-wrap-its-content/ 如果把Grid ...
- (贪心)kruskal思想
hdu4313 Matrix Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) T ...
- vuls漏洞扫描工具
Vuls 是一款适用于 Linux/FreeBSD 的漏洞扫描程序,无代理,采用 Go 语言编写,对于系统管理员来说,每天必须执行安全漏洞分析和软件更新都是一个负担. 为避免生产环境宕机,系统管理员通 ...
- c#中类和对象详解
1.1 类和对象 类 (class) 是最基础的 C# 类型.类是一个数据结构,将状态(字段)和操作(方法和其他函数成员)组合在一个单元中.类为动态创建的类实例 (instance) 提供了定义,实例 ...
- CodeForces 19D Points (线段树+set)
D. Points time limit per test 2 seconds memory limit per test 256 megabytes input standard input out ...
- python threading.thread
Thread 是threading模块中最重要的类之一,可以使用它来创建线程.有两种方式来创建线程:一种是通过继承Thread类,重写它的run方法:另一种是创建一个threading.Thread对 ...
- 使用Navicat连接Mysql报错:can not get hostname for your address
以管理员的身份使用cmd命令运行netsh winsock reset即可!
- MySQL中数据表的查操作
查询数据表的全部内容 mysql> show tables;#查看当前数据库下的全部表 +--------------------+ | Tables_in_ceshi_ku | +------ ...
- Alpine Linux配置使用技巧【一个只有5M的操作系统(转)】
Alpine Linux是一个面向安全应用的轻量级Linux发行版.它采用了musl libc和busybox以减小系统的体积和运行时资源消耗,同时还提供了自己的包管理工具apk. Alpine Li ...
- Winform 下使用WebBrowser的HTML编辑控件—WinHtmlControl 在win7 IE9下的问题
问题是这样的,有一个需要用到富文本的地方,由于是winform的程序,而且程序是上一代老员工留下的,错误百出,现在要尽量修复,至少保证能正常使用,于是就开始一点点问题修复. 在win7 64位系统下出 ...