Menu
Coddy logo textTech

参照クラスの定義

CoddyのRジャーニー「オブジェクト指向プログラミング」セクションの一部。レッスン 37/57。

参照クラス(RC)は、JavaやPythonのように、その場で変更されるオブジェクトのためのRのシステムです。setRefClass()は、型付きのフィールドを持つクラスを宣言し、ジェネレーターを返します。$new()はオブジェクトを作成し、$はそのフィールドの読み取りと変更を行います:

Account <- setRefClass("Account", fields = list(owner = "character", balance = "numeric"))
a <- Account$new(owner = "Ada", balance = 100)
a$balance <- a$balance + 50
cat(a$owner, a$balance)

出力:

Ada 150

RC オブジェクトは、環境と同様に参照です。別の変数に代入したり、関数に渡したりしてもコピーされないため、どの名前を通じて変更しても、同じ 1 つのオブジェクトへの変更になります:

Account <- setRefClass("Account", fields = list(owner = "character", balance = "numeric"))
pay_fee <- function(acc) acc$balance <- acc$balance - 5
a <- Account$new(owner = "Ada", balance = 100)
b <- a
b$balance <- 60
pay_fee(a)
cat(a$balance, b$balance)

出力:

55 55

フィールドには型があります。誤ったクラスの値を代入すると拒否され、フィールドは元の値を保持します。

Account <- setRefClass("Account", fields = list(owner = "character", balance = "numeric"))
a <- Account$new(owner = "Ada", balance = 100)
msg <- tryCatch({ a$balance <- "lots"; "changed" }, error = function(e) conditionMessage(e))
cat(msg, "\n")
cat(a$balance, "\n")

出力:

invalid assignment for reference class field ‘balance’, should be from class “numeric” or a subclass (was class “character”) 
100 

ジェネレーターはクラスを説明します。Account$fields() はフィールドとその型を一覧表示します。show メソッドを持たないオブジェクトを出力すると、そのフィールドが一覧表示されます。値が与えられていないフィールドは空です。

Account <- setRefClass("Account", fields = list(owner = "character", balance = "numeric"))
print(Account$fields())
Account$new(owner = "Bo")

出力:

      owner     balance 
"character"   "numeric" 
Reference class object of class "Account"
Field "owner":
[1] "Bo"
Field "balance":
numeric(0)
challenge icon

チャレンジ

簡単

Book 参照クラスを Book.R で宣言し、フィールドとして title と author(character)、pages(numeric)を定義して、生成器を Book に保持してください。次に、add_pages(book, n) を記述し、書籍の pages に n をその場で加算し、有用な値は何も返さないようにしてください。

提供されたコードは title;author;pages を読み取り、書籍を作成し、それを 2 番目の変数に代入して、その 2 番目の名前を通じて残りの数値を加算し、元の書籍とフィールド名を出力します。

コードは Book.R に記述してください。main.R には提供された入出力コードが含まれており、編集できません。

自分で試してみよう

source("Book.R")

# 提供された入出力コード: そのままにしておく
input <- suppressWarnings(readLines(file("stdin")))
p <- strsplit(input[1], ";")[[1]]
b <- Book$new(title = p[1], author = p[2], pages = as.numeric(p[3]))
alias <- b
for (n in as.numeric(input[-1])) add_pages(alias, n)
cat(b$title, " by ", b$author, ": ", b$pages, " pages\n", sep = "")
cat("fields: ", paste(names(Book$fields()), collapse = ", "), "\n", sep = "")
quiz icon腕試し

このレッスンには短いクイズがあります。レッスンを始めて解答し、進捗を記録しましょう。

オブジェクト指向プログラミングのすべてのレッスン

自分で練習してみよう: Rオンラインコンパイラ