메서드와 필드 업데이트
Coddy R 여정의 객체 지향 프로그래밍 섹션에 포함된 레슨. 57개 중 38번째.
메서드는 setRefClass()의 methods 목록에 넣습니다. 메서드 안에서 필드는 일반적인 이름으로 사용되며, <<-는 필드를 변경합니다. Coddy 러너에서는 메서드가 있는 클래스를 정의할 때 선택 사항인 codetools 패키지에 대한 안내 메시지를 R이 출력하므로, 정의를 suppressMessages()로 감싸세요:
Counter <- suppressMessages(setRefClass("Counter",
fields = list(count = "numeric"),
methods = list(
add = function(n = 1) {
count <<- count + n
},
report = function() paste("count is", count)
)
))
c1 <- Counter$new(count = 0)
c1$add()
c1$add(5)
print(c1$report())출력:
[1] "count is 6".self는 메서드가 호출된 객체입니다. invisible(.self)로 끝나는 메서드는 객체를 반환하므로 호출을 연쇄적으로 연결할 수 있습니다:
Counter <- suppressMessages(setRefClass("Counter",
fields = list(count = "numeric"),
methods = list(
add = function(n = 1) {
count <<- count + n
invisible(.self)
}
)
))
c1 <- Counter$new(count = 0)
c1$add(2)$add(3)$add(4)
print(c1$count)출력:
[1] 9initialize 메서드는 $new() 내부에서 실행됩니다. initFields(...)는 전달된 필드를 설정하며, 이후 메서드는 나머지 필드에 기본값을 지정할 수 있습니다. 메서드는 이름으로 서로 호출합니다:
Account <- suppressMessages(setRefClass("Account",
fields = list(owner = "character", balance = "numeric"),
methods = list(
initialize = function(...) {
initFields(...)
if (length(balance) == 0) balance <<- 0
invisible(.self)
},
deposit = function(x) balance <<- balance + x,
deposit_twice = function(x) {
deposit(x)
deposit(x)
}
)
))
a <- Account$new(owner = "Ada")
a$deposit_twice(10)
print(a$balance)출력:
[1] 20메서드 내부에서 필드 이름에 일반적인 <-를 사용하면 해당 이름의 지역 변수가 생성되고 필드는 변경되지 않습니다. 필드를 변경할 때마다 <<-를 사용하세요:
Counter <- suppressMessages(setRefClass("Counter",
fields = list(count = "numeric"),
methods = list(
broken = function() count <- count + 1,
working = function() count <<- count + 1
)
))
c1 <- Counter$new(count = 0)
c1$broken()
c1$broken()
c1$working()
print(c1$count)출력:
[1] 1챌린지
쉬움Stack 참조 클래스를 Stack.R에서 완성하세요. 이 클래스는 필드 items에 항목을 저장하며(문자형이고, 마지막 항목이 가장 위에 있음) 네 가지 메서드를 가집니다:
push(x)는x를 맨 위에 추가하고invisible(.self)를 반환하므로, 여러 push를 연결할 수 있습니다;pop()은 맨 위 항목을 제거하고 반환하며, 스택이 비어 있으면nothing을 반환합니다;peek()은 맨 위 항목을 제거하지 않고 반환하며, 비어 있으면nothing을 반환합니다;size()는 항목의 개수를 반환합니다.
정의는 이미 suppressMessages()로 감싸져 있습니다. 제공된 코드는 push a b, pop, peek 명령을 읽은 다음, 연결된 호출 하나로 항목을 두 개 더 추가하고 크기를 출력합니다.
코드는 Stack.R에 작성하세요. main.R에는 제공된 입력/출력 코드가 들어 있으며 수정할 수 없습니다.
직접 해보기
source("Stack.R")
# 제공된 입력/출력 코드: 그대로 유지하세요
input <- suppressWarnings(readLines(file("stdin")))
s <- Stack$new()
for (cmd in input) {
if (startsWith(cmd, "push ")) {
items <- strsplit(substring(cmd, 6), " ")[[1]]
for (it in items) s$push(it)
} else if (cmd == "pop") {
cat("popped ", s$pop(), "\n", sep = "")
} else if (cmd == "peek") {
cat("top ", s$peek(), "\n", sep = "")
}
}
s$push("x")$push("y")
cat("size after two chained pushes: ", s$size(), "\n", sep = "")
이 레슨에는 짧은 퀴즈가 포함되어 있습니다. 레슨을 시작해 문제를 풀고 진행 상황을 기록하세요.
객체 지향 프로그래밍의 모든 레슨
직접 연습해 보세요: 온라인 R 컴파일러