제네릭과 UseMethod
Coddy R 여정의 객체 지향 프로그래밍 섹션에 포함된 레슨. 57개 중 7번째.
제네릭은 본문이 UseMethod("name")인 함수입니다. 호출되면 첫 번째 인수의 클래스를 확인하고 name.class 메서드를 호출합니다. print()와 format()이 이런 방식으로 작동하며, 직접 제네릭을 작성할 수도 있습니다.
speak <- function(x) UseMethod("speak")
speak.dog <- function(x) paste(x$name, "says woof")
speak.cat <- function(x) paste(x$name, "says meow")
rex <- structure(list(name = "Rex"), class = "dog")
tom <- structure(list(name = "Tom"), class = "cat")
print(speak(rex))
print(speak(tom))출력:
[1] "Rex says woof"
[1] "Tom says meow"호출자는 하나의 호출을 작성하고, 각 객체는 자신만의 방식으로 응답합니다. 이것이 다형성입니다. 혼합된 목록을 순회하는 코드는 각 클래스마다 if를 작성할 필요가 없습니다:
speak <- function(x) UseMethod("speak")
speak.dog <- function(x) paste(x$name, "says woof")
speak.cat <- function(x) paste(x$name, "says meow")
pets <- list(structure(list(name = "Rex"), class = "dog"),
structure(list(name = "Tom"), class = "cat"),
structure(list(name = "Bo"), class = "dog"))
for (p in pets) cat(speak(p), "\n")출력:
Rex says woof
Tom says meow
Bo says woof 메서드는 제네릭의 인수를 받습니다. 메서드가 원의 digits와 같이 자체적인 추가 인수를 받을 수 있도록 제네릭에 ... 매개변수를 지정하세요:
area <- function(shape, ...) UseMethod("area")
area.square <- function(shape, ...) shape$side^2
area.circle <- function(shape, digits = 2, ...) round(pi * shape$r^2, digits)
sq <- structure(list(side = 3), class = "square")
ci <- structure(list(r = 1), class = "circle")
print(area(sq))
print(area(ci))
print(area(ci, digits = 4))출력:
[1] 9
[1] 3.14
[1] 3.1416UseMethod()는 호출을 메서드에 넘기고 절대 돌아오지 않습니다. 메서드가 반환하는 값이 제네릭의 결과가 되며, UseMethod() 뒤의 코드는 실행되지 않습니다. 따라서 제네릭은 한 줄입니다:
size <- function(x) {
UseMethod("size")
cat("this line never runs\n")
}
size.box <- function(x) x$w * x$h
b <- structure(list(w = 2, h = 5), class = "box")
print(size(b))출력:
[1] 10챌린지
쉬움도형은 세 개의 파일로 나뉘어 있습니다. Shape.R의 일반 area()를 완성한 다음, Circle.R에 area.circle()(반지름의 제곱에 pi를 곱한 값), Rectangle.R에 area.rectangle()(너비에 높이를 곱한 값) 메서드를 추가하세요. 생성자는 제공됩니다.
제공된 코드는 circle 2 또는 rectangle 3 4 형식의 줄을 읽고 각 도형의 클래스와 넓이를 소수점 이하 두 자리로 출력합니다: circle: 12.57.
코드는 Shape.R, Circle.R, Rectangle.R에 작성하세요. main.R에는 제공된 입력/출력 코드가 있으며 편집할 수 없습니다.
직접 해보기
source("Shape.R")
source("Circle.R")
source("Rectangle.R")
# 제공된 입력/출력 코드: 그대로 유지하세요
input <- suppressWarnings(readLines(file("stdin")))
for (line in input) {
p <- strsplit(line, " ")[[1]]
s <- if (p[1] == "circle") new_circle(as.numeric(p[2])) else new_rectangle(as.numeric(p[2]), as.numeric(p[3]))
cat(sprintf("%s: %.2f", class(s), area(s)), "\n", sep = "")
}
이 레슨에는 짧은 퀴즈가 포함되어 있습니다. 레슨을 시작해 문제를 풀고 진행 상황을 기록하세요.
객체 지향 프로그래밍의 모든 레슨
직접 연습해 보세요: 온라인 R 컴파일러