Menu
CoddyTech

基础泛型的方法

本课属于 Coddy R 学习旅程的“面向对象编程”单元。第 9 课,共 57 课。

base R 中的许多函数都是 S3 泛型函数:print()、format()、summary()、toString()、length()、as.character() 等。添加一个方法,就能让你的类与每个 R 用户都熟悉的函数配合使用。summary.gradebook() 会汇总整个对象:

summary.gradebook <- function(object, ...) {
  paste0(length(object$marks), " marks, average ", mean(object$marks))
}
g <- structure(list(marks = c(70, 85, 91)), class = "gradebook")
cat(summary(g), "\n")

输出:

3 marks, average 82 

在编写方法之前,先检查泛型的参数:summary() 将第一个参数称为 object,而 toString() 和 format() 将它称为 x。toString() 应返回一个字符串:

toString.gradebook <- function(x, ...) paste(x$marks, collapse = " / ")
g <- structure(list(marks = c(70, 85, 91)), class = "gradebook")
print(toString(g))

输出:

[1] "70 / 85 / 91"

length() 方法会改变 length() 对这个类的含义。队列可以把项目存储在一个字段中,并报告它包含多少个项目,而不是列表中的字段数量:

q <- structure(list(items = c("a", "b", "c"), name = "jobs"), class = "queue")
print(length(q))
length.queue <- function(x) length(x$items)
print(length(q))

输出:

[1] 2
[1] 3

运算符也可以是泛型。名为 "+.money" 的方法因为包含符号而用引号括起来;当 + 任一侧是 money 对象时,就会运行。它会将两侧分别作为 e1 和 e2 接收:

new_money <- function(amount) structure(list(amount = amount), class = "money")
"+.money" <- function(e1, e2) new_money(e1$amount + e2$amount)
"==.money" <- function(e1, e2) e1$amount == e2$amount
a <- new_money(5)
b <- new_money(7)
print((a + b)$amount)
print(a == b)

输出:

[1] 12
[1] FALSE
challenge icon

挑战

简单

栈会将元素保存在 items 字段中,栈顶元素位于最后。Stack.R 中已提供 new_stack()、push() 和 pop()。请添加三个方法:

  • length.stack() 返回元素数量。
  • toString.stack() 按从栈顶到栈底的顺序返回元素,并用 | 连接;如果栈为空,则返回 empty。
  • summary.stack() 返回 stack of 3, top: c;如果栈为空,则返回 stack of 0。

提供的代码会读取 push <item> 和 pop 命令,然后输出长度、toString() 和 summary()。

请将代码写在 Stack.R 中。main.R 包含提供的输入/输出代码,不能编辑。

亲手试试

source("Stack.R")

# 提供的输入和输出代码:保持原样
input <- suppressWarnings(readLines(file("stdin")))
s <- new_stack()
for (cmd in input) {
  if (cmd == "pop") s <- pop(s) else s <- push(s, substring(cmd, 6))
}
cat("length: ", length(s), "\n", sep = "")
cat("items: ", toString(s), "\n", sep = "")
cat(summary(s), "\n", sep = "")
quiz icon自我测试

这节课包含一个小测验。开始学习即可作答,并记录你的进度。

面向对象编程中的所有课

自己练习: R 在线编译器