Menu
CoddyTech

Generic'ler Oluşturma

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

Bir S4 genel işlevi setGeneric() ile oluşturulur. İşlev gövdesi, UseMethod()'un S4 karşılığı olan standardGeneric("name") ifadesidir. setGeneric(), genel işlevin adını döndürür; bu ad, işlev en üst düzeyde çağrıldığında yazdırılır:

setGeneric("area", function(shape) standardGeneric("area"))

Çıktı:

[1] "area"

Bu satırı çıktının dışında tutmak için çağrıyı invisible() içine alın. setMethod("area", "Circle", ...) ardından tek bir sınıf için yöntemi ekler:

setClass("Circle", slots = c(r = "numeric"))
setClass("Square", slots = c(side = "numeric"))
invisible(setGeneric("area", function(shape) standardGeneric("area")))
setMethod("area", "Circle", function(shape) pi * shape@r^2)
setMethod("area", "Square", function(shape) shape@side^2)
cat(area(new("Circle", r = 1)), area(new("Square", side = 3)))

Çıktı:

3.141593 9

Bir yöntem, genel yöntemiyle aynı bağımsız değişkenlere sahiptir. Genel yöntemde ... varsa, bir yöntem bunlardan sonra kendi adlandırılmış bağımsız değişkenlerini ekleyebilir:

setClass("Circle", slots = c(r = "numeric"))
invisible(setGeneric("describe", function(x, ...) standardGeneric("describe")))
setMethod("describe", "Circle", function(x, ..., digits = 2) {
  paste("circle of area", round(pi * x@r^2, digits))
})
c1 <- new("Circle", r = 2)
print(describe(c1))
print(describe(c1, digits = 4))

Çıktı:

[1] "circle of area 12.57"
[1] "circle of area 12.5664"

setMethod() için generic'in önceden var olması gerekir; bu nedenle setGeneric() içeren dosya önce kaynak olarak yüklenir. Bir yöntemi olmayan sınıf için yapılan çağrı, imzayı belirten bir hatayla durur:

invisible(setGeneric("area", function(shape) standardGeneric("area")))
setClass("Circle", slots = c(r = "numeric"))
setMethod("area", "Circle", function(shape) pi * shape@r^2)
area(42)

Çıktı:

Error: unable to find an inherited method for function ‘area’ for signature ‘shape = "numeric"’
Execution halted
challenge icon

Görev

Kolay

Şekiller, üç dosyada tanımlanan S4 sınıflarıdır. Shape.R dosyasında setGeneric() ile area(shape) ve perimeter(shape) generiklerini oluşturup invisible() içine alın. Circle.R ve Square.R dosyalarında sınıflar tanımlanır; her biri için setMethod() ile area ve perimeter yöntemlerini ekleyin.

Verilen kod, circle 2 veya square 3 satırlarını okur ve circle: area 12.57, perimeter 12.57 çıktısını verir.

Kodunuz Shape.R, Circle.R ve Square.R dosyalarına yazılmalıdır. main.R dosyası, verilen giriş/çıkış kodunu içerir ve düzenlenemez.

Kendin dene

source("Shape.R")
source("Circle.R")
source("Square.R")

# Sağlanan giriş/çıkış kodu: olduğu gibi bırakın
input <- suppressWarnings(readLines(file("stdin")))
for (line in input) {
  p <- strsplit(line, " ")[[1]]
  s <- if (p[1] == "circle") new("Circle", r = as.numeric(p[2])) else new("Square", side = as.numeric(p[2]))
  cat(sprintf("%s: area %.2f, perimeter %.2f", p[1], area(s), perimeter(s)), "\n", sep = "")
}
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