Menu
Coddy logo textTech

제네릭 만들기

Coddy R 여정의 객체 지향 프로그래밍 섹션에 포함된 레슨. 57개 중 27번째.

S4 제네릭은 setGeneric()으로 생성합니다. 함수 본문은 standardGeneric("name")이며, 이는 UseMethod()에 대응하는 S4 방식입니다. setGeneric()은 제네릭의 이름을 반환하며, 최상위 수준에서 호출하면 해당 이름이 출력됩니다:

setGeneric("area", function(shape) standardGeneric("area"))

출력:

[1] "area"

invisible()로 호출을 감싸 해당 줄이 출력에 나타나지 않도록 합니다. 그런 다음 setMethod("area", "Circle", ...)가 한 클래스에 대한 메서드를 추가합니다:

setClass("Circle", slots = c(r = "numeric"))
setClass("Square", slots = c(side = "numeric"))
invisible(setGeneric("area", function(shape) standardGeneric("area")))
setMethod("area", "Circle", function(shape) pi * shape@r^2)
setMethod("area", "Square", function(shape) shape@side^2)
cat(area(new("Circle", r = 1)), area(new("Square", side = 3)))

출력:

3.141593 9

메서드는 제네릭과 동일한 인수를 가집니다. 제네릭에 ...이 있으면 메서드는 그 뒤에 자체 명명된 인수를 추가할 수 있습니다:

setClass("Circle", slots = c(r = "numeric"))
invisible(setGeneric("describe", function(x, ...) standardGeneric("describe")))
setMethod("describe", "Circle", function(x, ..., digits = 2) {
  paste("circle of area", round(pi * x@r^2, digits))
})
c1 <- new("Circle", r = 2)
print(describe(c1))
print(describe(c1, digits = 4))

출력:

[1] "circle of area 12.57"
[1] "circle of area 12.5664"

setMethod()가 작동하려면 제네릭이 이미 존재해야 하므로, setGeneric()이 포함된 파일을 먼저 소스합니다. 메서드가 정의되지 않은 클래스에 대해 호출하면 시그니처를 명시하는 오류와 함께 실행이 중단됩니다.

invisible(setGeneric("area", function(shape) standardGeneric("area")))
setClass("Circle", slots = c(r = "numeric"))
setMethod("area", "Circle", function(shape) pi * shape@r^2)
area(42)

출력:

Error: unable to find an inherited method for function ‘area’ for signature ‘shape = "numeric"’
Execution halted
challenge icon

챌린지

쉬움

도형은 세 파일에 정의된 S4 클래스입니다. Shape.R에서 invisible()로 감싼 setGeneric()을 사용하여 area(shape)와 perimeter(shape) 제네릭을 만드세요. Circle.R과 Square.R에서는 클래스를 선언하고, setMethod()를 사용하여 각각의 area 및 perimeter 메서드를 추가하세요.

제공된 코드는 circle 2 또는 square 3 형식의 줄을 읽고 circle: area 12.57, perimeter 12.57을 출력합니다.

코드는 Shape.R, Circle.R 및 Square.R에 작성하세요. main.R에는 제공된 입력/출력 코드가 들어 있으며 편집할 수 없습니다.

직접 해보기

source("Shape.R")
source("Circle.R")
source("Square.R")

# 제공된 입력/출력 코드: 그대로 유지하세요
input <- suppressWarnings(readLines(file("stdin")))
for (line in input) {
  p <- strsplit(line, " ")[[1]]
  s <- if (p[1] == "circle") new("Circle", r = as.numeric(p[2])) else new("Square", side = as.numeric(p[2]))
  cat(sprintf("%s: area %.2f, perimeter %.2f", p[1], area(s), perimeter(s)), "\n", sep = "")
}
quiz icon실력 점검

이 레슨에는 짧은 퀴즈가 포함되어 있습니다. 레슨을 시작해 문제를 풀고 진행 상황을 기록하세요.

객체 지향 프로그래밍의 모든 레슨

직접 연습해 보세요: 온라인 R 컴파일러