Menu
Coddy logo textTech

메서드 탐색 순서

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

각 호출마다 R은 클래스 벡터를 왼쪽에서 오른쪽으로 순회하며 처음 발견하는 메서드를 실행합니다. 어떤 클래스에도 메서드가 없으면 기본 메서드를 사용합니다. 하나의 계층 구조에 속한 서로 다른 객체는 서로 다른 수준에서 탐색을 멈출 수 있습니다:

move <- function(x) UseMethod("move")
move.animal <- function(x) "walks"
move.bird <- function(x) "flies"
move.default <- function(x) "stays"
penguin <- structure(list(), class = c("penguin", "bird", "animal"))
dog <- structure(list(), class = c("dog", "animal"))
rock <- structure(list(), class = "rock")
cat(move(penguin), move(dog), move(rock))

출력:

flies walks stays

자식은 자신의 메서드를 정의하여 부모 메서드를 재정의합니다. 재정의는 자식과 그 아래에 있는 항목에만 영향을 미치며, 부모와 다른 자식들은 부모 메서드를 그대로 유지합니다:

move <- function(x) UseMethod("move")
move.animal <- function(x) "walks"
move.bird <- function(x) "flies"
move.penguin <- function(x) "swims"
penguin <- structure(list(), class = c("penguin", "bird", "animal"))
sparrow <- structure(list(), class = c("bird", "animal"))
cat(move(penguin), move(sparrow))

출력:

swims flies

각 제네릭은 자체적으로 조회됩니다. 하나의 객체가 자신의 클래스에서 sound()를 가져오고 부모 클래스에서 move()를 가져올 수 있으며, 부모 메서드는 자식에 대해 다시 디스패치되는 다른 제네릭을 호출할 수 있습니다:

sound <- function(x) UseMethod("sound")
move <- function(x) UseMethod("move")
describe <- function(x) UseMethod("describe")
sound.animal <- function(x) "..."
sound.dog <- function(x) "woof"
move.animal <- function(x) "walks"
describe.animal <- function(x) paste(x$name, "says", sound(x), "and", move(x))
rex <- structure(list(name = "Rex"), class = c("dog", "animal"))
print(describe(rex))

출력:

[1] "Rex says woof and walks"

클래스 속성이 있는 객체의 경우, 디스패치는 해당 속성만 확인한 다음 기본값을 확인합니다. 객체는 내부적으로 여전히 리스트이지만, list를 위한 메서드는 시도되지 않습니다:

size <- function(x) UseMethod("size")
size.list <- function(x) "a list"
size.default <- function(x) "default"
bag <- structure(list(1, 2), class = "bag")
cat(size(list(1, 2)), "/", size(bag))

출력:

a list / default
challenge icon

챌린지

쉬움

정사각형은 변의 길이가 같은 직사각형입니다. Rectangle.R에 rectangle 2x3을 반환하는 area.rectangle(), perimeter.rectangle() 및 name.rectangle() 메서드를 작성하세요. Square.R에서는 new_rectangle()을 클래스 square와 함께 호출하는 new_square(side)를 완성하고, square 2를 반환하는 name.square()로 name()만 재정의하세요. 정사각형은 직사각형의 area()와 perimeter()를 사용해야 합니다.

제네릭과 new_rectangle()은 제공됩니다. 제공된 코드는 두 개의 숫자(직사각형) 또는 하나의 숫자(정사각형)가 있는 줄을 읽고 square 2: area 4, perimeter 8을 출력합니다.

코드는 Rectangle.R과 Square.R에 작성하세요. main.R에는 제공된 입력/출력 코드가 있으며 수정할 수 없습니다.

직접 해보기

source("Rectangle.R")
source("Square.R")

# 제공된 입력/출력 코드: 있는 그대로 유지하세요
input <- suppressWarnings(readLines(file("stdin")))
for (line in input) {
  n <- as.numeric(strsplit(line, " ")[[1]])
  s <- if (length(n) == 1) new_square(n[1]) else new_rectangle(n[1], n[2])
  cat(name(s), ": area ", area(s), ", perimeter ", perimeter(s), "\n", sep = "")
}
quiz icon실력 점검

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

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

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