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. 【Android】Scrollview 相关问题汇总

    去除Scrollview 滑动边界渐变颜色 去掉滚动条,并将在滑动时,边界不会变成灰白 <horizontalscrollview android:overScrollMode="ne ...

  2. 使用Spring报错:No default constructor found;

    Exception in thread "main" org.springframework.beans.factory.BeanCreationException: Error ...

  3. create sequence

    create sequence seq_test start with 3 increment by 1 minvalue 1  --范围-(1027 -1) maxvalue 99999999999 ...

  4. [MongoDB] 安装MongoDB配置Replica Set

    MongoDB的环境主要包括StandAlone,Replication和Sharding. StandAlone:单机环境,一般开发测试的时候用. Replication:主从结构,一个Primar ...

  5. vsftpd文件服务器安装与配置

    -d<登入目录>:指定用户登入时的启始目录:. -s<shell>:指定用户登入后所使用的shell: /sbin/nologin指的是不允许login当前Linux系统.当用 ...

  6. PAT 1046 Shortest Distance[环形][比较]

    1046 Shortest Distance(20 分) The task is really simple: given N exits on a highway which forms a sim ...

  7. RedHat Linux文本模式下乱码解决方法

    如果在安装RedHat Linux时选择中文未缺省语言,在文本模式下会出现乱码情况,对于在CLI(command-line interface,命令行界面)方式下调试程序时诸多不便,因为出错信息全是乱 ...

  8. Django中间件的5种自定义方法

    阅读目录(Content) Django中间件 自定义中间件 中间件(类)中5种方法 中间件应用场景 回到顶部(go to top) Django中间件 在http请求 到达视图函数之前   和视图函 ...

  9. Which adidas NMD Singapore is your favorite

    The adidas NMD Singapore just keeps the hits coming this fall with another change that's sure to bec ...

  10. 38初识xml

    XML(可扩展标记语言)是一种用于记录多种数据类型的标记语言.使用XML可以将各类型的文档定义为容易读取的格式,便于用户读取.而且,在应用程序中使用XML,可以轻松实现数据交换. QT中提供两种访问X ...