Menu
Coddy logo textTech

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 jeneriği setGeneric() ile oluşturulur. İşlev gövdesi, UseMethod() karşılığı olan standardGeneric("name") ifadesidir. setGeneric(), jeneriğin adını döndürür; üst düzeyde çağrıldığında bu ad 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() ile sarın. Ardından setMethod("area", "Circle", ...), 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öntem ... içerdiğinde, bir yöntem bunlardan sonra kendine ait adlandırılmış bağımsız değişkenler 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() genel fonksiyonun önceden mevcut olmasını gerektirir; bu nedenle setGeneric() içeren dosya önce kaynaklanır. Bir yöntem olmadan bir 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, üç dosyadaki S4 sınıflarıdır. Shape.R içinde setGeneric() kullanarak ve invisible() ile sararak area(shape) ve perimeter(shape) generic fonksiyonlarını oluştur. Circle.R ve Square.R içinde sınıflar tanımlanır; her birinin area ve perimeter metotlarını setMethod() ile ekle.

Sağlanan kod, circle 2 veya square 3 satırlarını okur ve circle: area 12.57, perimeter 12.57 çıktısını yazdırır.

Kodun Shape.R, Circle.R ve Square.R dosyalarına yazılır. main.R, sağlanan girdi/çıktı kodunu içerir ve düzenlenemez.

Kendin dene

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

# Sağlanan girdi/çıktı 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