제네릭 만들기
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챌린지
쉬움도형은 세 개의 파일에 정의된 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 = "")
}
이 레슨에는 짧은 퀴즈가 포함되어 있습니다. 레슨을 시작해 문제를 풀고 진행 상황을 기록하세요.
객체 지향 프로그래밍의 모든 레슨
직접 연습해 보세요: 온라인 R 컴파일러