showメソッド
CoddyのRジャーニー「オブジェクト指向プログラミング」セクションの一部。レッスン 25/57。
S4オブジェクトが表示されると、Rは関数 show() を呼び出します。クラス用のメソッドがない場合、すべてのスロットを一覧表示します。これは正しいものの、長くなります。
setClass("Point", slots = c(x = "numeric", y = "numeric"))
p <- new("Point", x = 1, y = 2)
p出力:
An object of class "Point"
Slot "x":
[1] 1
Slot "y":
[1] 2setMethod("show", "Point", function(object) ...) はクラス独自の表示方法を与えます。このメソッドは cat() を使って出力し、オブジェクトがトップレベルで表示されるときと、print() によって表示されるときの両方で使用されます。
setClass("Point", slots = c(x = "numeric", y = "numeric"))
setMethod("show", "Point", function(object) {
cat("Point(", object@x, ", ", object@y, ")\n", sep = "")
})
p <- new("Point", x = 1, y = 2)
p
print(p)出力:
Point(1, 2)
Point(1, 2)スロットには別の S4 オブジェクトを保持できます。その型をクラス名として宣言します。外側の show() メソッドは、内部オブジェクトに対して show() を呼び出すことで、そのオブジェクトを出力できます。
setClass("Point", slots = c(x = "numeric", y = "numeric"))
setMethod("show", "Point", function(object) cat("(", object@x, ", ", object@y, ")", sep = ""))
setClass("Line", slots = c(from = "Point", to = "Point"))
setMethod("show", "Line", function(object) {
cat("line ")
show(object@from)
cat(" -> ")
show(object@to)
cat("\n")
})
new("Line", from = new("Point", x = 0, y = 0), to = new("Point", x = 3, y = 4))出力:
line (0, 0) -> (3, 4)仮想クラスは、representation("VIRTUAL")で宣言され、new()で作成することはできません。これは、S4継承の章で基盤となる、他のクラスの共通の親として存在します。isVirtualClass()は、この2種類を見分けます:
setClass("Shape", representation("VIRTUAL"))
setClass("Point", slots = c(x = "numeric"))
cat(isVirtualClass("Shape"), isVirtualClass("Point"), "\n")
msg <- tryCatch(new("Shape"), error = function(e) "cannot create a Shape")
cat(msg, "\n")出力:
TRUE FALSE
cannot create a Shape チャレンジ
簡単点と線分は、2つのファイルに分かれた2つのS4クラスです。クラスは宣言済みです。それらのshow()メソッドを追加してください。
Point.Rでは、点をPoint(1, 2)の形式で出力し、その後に改行します。Segment.Rでは、線分をSegment Point(1, 2) to Point(4, 6), length 5の形式で出力し、その後に改行します。長さは小数点以下2桁に丸めます。点のテキストは自分で作成するか、ヘルパーを使ってください。点のメソッドは独自に改行を出力するため、線分の行の途中で呼び出さないでください。
提供されたコードは1,2 4,6という行を読み込み、最初の点を出力してから、線分を出力します。どちらもそれぞれのshow()メソッドを通じて出力されます。
コードはPoint.RとSegment.Rに記述します。main.Rには提供された入力/出力コードが含まれており、編集できません。
自分で試してみよう
source("Point.R")
source("Segment.R")
# 提供された入出力コード: そのままにしておく
input <- suppressWarnings(readLines(file("stdin")))
for (line in input) {
n <- as.numeric(strsplit(line, "[ ,]")[[1]])
a <- new("Point", x = n[1], y = n[2])
b <- new("Point", x = n[3], y = n[4])
print(a)
print(new("Segment", from = a, to = b))
}
このレッスンには短いクイズがあります。レッスンを始めて解答し、進捗を記録しましょう。
オブジェクト指向プログラミングのすべてのレッスン
自分で練習してみよう: Rオンラインコンパイラ