Menu
Coddy logo textTech

inherits() ile Denetleme

Coddy'nin R Journey'sinin Nesne Tabanlı Programlama bölümünün bir parçası. Ders 15 / 57.

inherits(x, "employee"), employee'ın x'in sınıf vektöründe herhangi bir yerde olup olmadığını sorar; bu nedenle yöneticiler için de TRUE değerini verir. class(x) == "employee" ile karşılaştırma her konumu ayrı ayrı kontrol eder ve bir vektör döndürür; bu da bir if içinde hataya neden olur:

m <- structure(list(), class = c("manager", "employee"))
print(inherits(m, "employee"))
print(inherits(m, "intern"))
print(class(m) == "employee")

Çıktı:

[1] TRUE
[1] FALSE
[1] FALSE  TRUE

Birden fazla ad verildiğinde, inherits() nesne bunlardan herhangi birine sahipse TRUE değerini döndürür. which = TRUE ile her ad için sınıf vektöründeki konumunu, ad eksik olduğunda ise 0 değerini döndürür:

p <- structure(list(), class = c("fragile", "express", "parcel"))
print(inherits(p, c("letter", "parcel")))
print(inherits(p, c("express", "letter", "parcel"), which = TRUE))

Çıktı:

[1] TRUE
[1] 2 0 3

Yalnızca bir sınıf ailesi için anlamlı olan bir işlev, bağımsız değişkenini inherits() ile denetler ve aksi durumda anlaşılır bir iletiyle durur:

raise <- function(x, pct) {
  if (!inherits(x, "employee")) stop("raise() needs an employee", call. = FALSE)
  x$salary <- x$salary * (1 + pct / 100)
  x
}
m <- structure(list(salary = 50000), class = c("manager", "employee"))
print(raise(m, 10)$salary)
print(tryCatch(raise(list(salary = 1), 10), error = function(e) conditionMessage(e)))

Çıktı:

[1] 55000
[1] "raise() needs an employee"

Filter() ile inherits(), her alt sınıf da dahil olmak üzere, karışık bir listeden bir aileye ait üyeleri seçer:

staff <- list(
  structure(list(name = "Ada"), class = c("manager", "employee")),
  structure(list(name = "Bo"), class = "employee"),
  structure(list(name = "Cy"), class = c("intern", "employee")),
  structure(list(name = "Dee"), class = c("director", "manager", "employee"))
)
managers <- Filter(function(x) inherits(x, "manager"), staff)
print(vapply(managers, function(x) x$name, character(1)))

Çıktı:

[1] "Ada" "Dee"
challenge icon

Görev

Kolay

Bir katalog kitapları, e-kitapları ve DVD'leri barındırır. Yapıcılar Item.R, Book.R, Ebook.R ve Dvd.R dosyalarında verilmiştir; bir e-kitabın sınıfı c("ebook", "book", "item") olur. Catalogue.R dosyasında inherits() kullanarak iki işlevi tamamlayın:

  • count_of(items, kind), sınıf vektörlerinde herhangi bir yerde kind bulunan öğelerin kaç tane olduğunu döndürür.
  • titles_of(items, kind), bu öğelerin başlıklarını kendi sıralarıyla döndürür.

Sağlanan kod book Dune, ebook Emma, dvd Alien satırlarını okur ve ? book sorgularını işler; ardından book: 2 (Dune, Emma) çıktısını yazdırır veya eşleşme olmadığında yalnızca dvd: 0 çıktısını verir.

Kodunuz Item.R, Book.R, Ebook.R, Dvd.R ve Catalogue.R dosyalarına yazılmalıdır. main.R sağlanan girdi/çıktı kodunu içerir ve düzenlenemez.

Kendin dene

source("Item.R")
source("Book.R")
source("Ebook.R")
source("Dvd.R")
source("Catalogue.R")

# Sağlanan girdi/çıktı kodu: olduğu gibi bırakın
input <- suppressWarnings(readLines(file("stdin")))
items <- list()
for (line in input) {
  p <- strsplit(line, " ")[[1]]
  rest <- paste(p[-1], collapse = " ")
  if (p[1] == "?") {
    titles <- titles_of(items, p[2])
    shown <- if (length(titles) > 0) paste0(" (", paste(titles, collapse = ", "), ")") else ""
    cat(p[2], ": ", count_of(items, p[2]), shown, "\n", sep = "")
  } else {
    items[[length(items) + 1]] <- switch(p[1], book = new_book(rest), ebook = new_ebook(rest), dvd = new_dvd(rest))
  }
}
quiz iconKendini test et

Bu ders kısa bir quiz içerir. Soruları yanıtlamak ve ilerlemeni kaydetmek için derse başla.

Nesne Tabanlı Programlama bölümündeki tüm dersler

Kendi başına pratik yap: Online R derleyicisi