Menu
Coddy logo textTech

제네릭과 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.1416

UseMethod()는 호출을 메서드에 넘기고 절대 돌아오지 않습니다. 메서드가 반환하는 값이 제네릭의 결과가 되며, 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
challenge icon

챌린지

쉬움

도형은 세 개의 파일로 나뉘어 있습니다. 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 = "")
}
quiz icon실력 점검

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

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

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