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. ...
随机推荐
- java设计模式----迭代子模式
顺序访问聚集中的对象,主要用于集合中.一是需要遍历的对象,即聚集对象,二是迭代器对象,用于对聚集对象进行遍历访问. 迭代子模式为遍历集合提供了统一的接口方法.从而使得客户端不需要知道聚集的内部结构就能 ...
- angular -- 无刷新做分页
无刷新做分页参考地址: http://www.jq22.com/demo/angular201707111100/ 示例代码: <!DOCTYPE html> <html lang= ...
- 最大网络流(Dinic)
hdu1532 Drainage Ditches Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java ...
- numeric_limits 模板的相关知识点
说白了,它是一个模板类,它主要是把C++当中的一些内建型别进行了封装,比如说numeric_limits<int>是一个特化后的类,从这个类的成员变量与成员函数中,我们可以了解到int的很 ...
- Linux系统下 Supervisor 安装搭建(yum安装)
安装Supervisor # 安装supervisor yum install supervisor # 打开supervisor的配置文件 vi /etc/supervisord.conf 将sup ...
- C++程序风格的思考
转载自:http://www.cppblog.com/weiym/archive/2013/04/27/199781.html 发现厚积薄发中有很多值得学习的东西 故引用之: 最近有机会看号称是公司最 ...
- 写一个体验良好的git commit
一直在使用git也看过格式各样commit log , review 代码时最刺激的是看到这类 "." 应付差事,还有 "fix bug","fix& ...
- SQL---->mySQl数据库1------jdbc简单入门
JDBC(Java Data Base Connectivity,java数据库连接)是一种用于执行SQL语句的Java API,可以为多种关系数据库提供统一访问. 目的:不用学习每个数据库的驱动,学 ...
- ABP 样板开发框架系列
--ABP 官网与源码 http://www.aspnetboilerplate.com/ https://github.com/aspnetboilerplate --pdf和docx 文档 htt ...
- mysql备份的4种方式
mysql备份的4种方式 转载自:https://www.cnblogs.com/SQL888/p/5751631.html 总结: 备份方法 备份速度 恢复速度 便捷性 功能 一般用于 cp 快 快 ...