Menu
Coddy logo textTech

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] 2

setMethod("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 
challenge icon

チャレンジ

簡単

点と線分は、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))
}
quiz icon腕試し

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

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

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